放送受信機をプログラムで登録するベストプラクティス/方法を教えてください。ユーザーの選択に従って特定のレシーバーを登録したい。
登録はマニフェストファイルを介して行われるため、コードでこれを実現する適切な方法があるかどうか疑問に思っています。
マニフェストで公開されたコンポーネントがアクティブであるかどうかを制御したいようですが、実行中に(Context.registerReceiver()を介して)レシーバーを動的に登録します。
その場合、PackageManager.setComponentEnabledSetting()を使用して、これらのコンポーネントがアクティブかどうかを制御できます。
実行中にブロードキャストの受信のみに関心がある場合は、registerReceiver()を使用することをお勧めします。レシーバーコンポーネントは、ブロードキャストが送信されるたびにアプリが起動されるようにする必要がある場合に主に役立ちます。
onCreate
メソッドで、次のようにレシーバーを登録できます。
private BroadcastReceiver receiver;
@Override
public void onCreate(Bundle savedInstanceState){
// your oncreate code should be
IntentFilter filter = new IntentFilter();
filter.addAction("SOME_ACTION");
filter.addAction("SOME_OTHER_ACTION");
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//do something based on the intent's action
}
};
registerReceiver(receiver, filter);
}
これをonDestroy
メソッドで忘れずに実行してください:
@Override
protected void onDestroy() {
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
super.onDestroy();
}
人々が言及することを忘れている重要な点の1つは、Broadcast Receiver
の寿命です。プログラムで登録することとAndroidManifest.xmlに登録することの違いはそれです。マニフェストファイルでは、アプリケーションの寿命に依存しません。一方、プログラムで登録するときは、アプリケーションの寿命に依存します。これは、AndroidManifest.xmlに登録すると、アプリケーションが実行されていなくてもブロードキャストされたインテントをキャッチできることを意味します。
編集:上記の注意はAndroid 3.1の時点では当てはまらず、Androidシステムはすべてのレシーバーを除外しますユーザーが対応するアプリケーションを一度も起動したことがない場合、またはユーザーがAndroidメニュー([管理]→[アプリケーション])で明示的にアプリケーションを停止した場合、デフォルトでインテントを受信しません。 https://developer.Android.com/about/versions/Android-3.1.html
これは追加のセキュリティ機能です。ユーザーは、開始したアプリケーションのみがブロードキャストインテントを受信することを確認できます。
したがって、アプリケーションのonCreate()
にプログラムで登録されたレシーバーは、Android 3.1のAndroidManifest.xmlで宣言されたレシーバーと同じ効果があると理解できます。上記。
次のように、アクティビティ/フラグメントの任意の場所にブロードキャストレシーバーを定義します。
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG," onRecieve"); //do something with intent
}
};
onCreate()
でIntentFilterを定義する
mIntentFilter=new IntentFilter("action_name");
次に、BroadcastRecieverをonResume()
に登録し、onPause()
で登録を解除します(アクティビティが一時停止している場合はブロードキャストを使用しないため)。
@Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
@Override
protected void onPause() {
if(mReceiver != null) {
unregisterReceiver(mReceiver);
mReceiver = null;
}
super.onPause();
}
詳細なチュートリアルについては、 ブロードキャストレシーバー-実装する2つの方法 をご覧ください。
package com.example.broadcastreceiver;
import Android.app.Activity;
import Android.content.IntentFilter;
import Android.os.Bundle;
import Android.view.Menu;
import Android.view.View;
import Android.widget.Toast;
public class MainActivity extends Activity {
UserDefinedBroadcastReceiver broadCastReceiver = new UserDefinedBroadcastReceiver();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* This method enables the Broadcast receiver for
* "Android.intent.action.TIME_TICK" intent. This intent get
* broadcasted every minute.
*
* @param view
*/
public void registerBroadcastReceiver(View view) {
this.registerReceiver(broadCastReceiver, new IntentFilter(
"Android.intent.action.TIME_TICK"));
Toast.makeText(this, "Registered broadcast receiver", Toast.LENGTH_SHORT)
.show();
}
/**
* This method disables the Broadcast receiver
*
* @param view
*/
public void unregisterBroadcastReceiver(View view) {
this.unregisterReceiver(broadCastReceiver);
Toast.makeText(this, "unregistered broadcst receiver", Toast.LENGTH_SHORT)
.show();
}
}
受信者を登録するときは常に許可を与えるのがベストプラクティスです。そうしないと、一致するインテントを送信するアプリケーションに対して受信します。これにより、悪意のあるアプリが受信者にブロードキャストできるようになります。
グローバルメッセージのリッスンとブロードキャスト、および 一般的なタスクでのアラームの設定とAndroidでのそれらの実行方法 によると:
マニフェストで受信クラスが登録されていない場合、Context.registerReceiver()を呼び出すことにより、受信側を動的にインスタンス化して登録できます。
詳細については、 registerReceiver(BroadcastReceiverレシーバー、IntentFilterフィルター)を参照してください 。
LocalBroadcastManager
Intent intent = new Intent("any.action.string");
LocalBroadcastManager.getInstance(context).
sendBroadcast(intent);
そしてonResume
に登録します
LocalBroadcastManager.getInstance(
ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);
登録を解除しますonStop
LocalBroadcastManager.getInstance(
ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);
そしてそれを受け取る..
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("mBroadcastReceiver", "onReceive");
}
};
intentFilterは
new IntentFilter("any.action.string")
1)アクティビティが表示されているときにのみブロードキャストを読みたい場合、
onStart()
のregisterReceiver(...
およびunregisterReceiver(...)
のonStop()
2)アクティビティがバックグラウンドにある場合でもブロードキャストを読みたい場合は、
registerReceiver(...)
のonCreate(...)
およびunregisterReceiver(...)
のonDestroy()
あなたが怠け者なら
各アクティビティでBroadcastReceiverを何度も登録および登録解除するための定型コードを記述したくない場合は、
ここにコードスニペットがあります:
抽象アクティビティ
public abstract class BasicActivity extends AppCompatActivity {
private BroadcastReceiver broadcastReceiver;
private IntentFilter filter;
private static final String TAG = "BasicActivity";
/**********************************************************************
* Boilerplate code
**********************************************************************/
@Override
public void onCreate(Bundle sis){
super.onCreate(sis);
broadcastReceiver = getBroadcastReceiver();
filter = getFilter();
}
@Override
public void onStart(){
super.onStart();
register();
}
@Override
public void onStop(){
super.onStop();
unregister();
}
private void register(){
registerReceiver(broadcastReceiver,filter);
}
private void unregister(){
unregisterReceiver(broadcastReceiver);
}
/**********************************************************************
* Abstract methods
**********************************************************************/
public abstract BroadcastReceiver getBroadcastReceiver();
public abstract IntentFilter getFilter();
}
このアプローチを使用すると、一般的なアニメーションの作成、サービスへのバインドなど、より定型的なコードを作成できます。
ブロードキャストレシーバーの作成
[BroadcastReceiver(Enabled = true、Exported = false)]
public class BCReceiver : BroadcastReceiver
{
BCReceiver receiver;
public override void OnReceive(Context context, Intent intent)
{
//Do something here
}
}
アクティビティからこのコードを追加:
LocalBroadcastManager.getInstance(ApplicationContext)
.registerReceiver(receiver, filter);