ブロードキャストレシーバーをプログラムで登録するためのベストプラクティス/方法を教えてください。ユーザーの選択に応じて特定の受信機を登録したい。
登録はマニフェストファイルを通じて行われるので、コードでこれを実現する適切な方法があるかどうか疑問に思っています。
ブロードキャストレシーバーをプログラムで登録するためのベストプラクティス/方法を教えてください。ユーザーの選択に応じて特定の受信機を登録したい。
登録はマニフェストファイルを通じて行われるので、コードでこれを実現する適切な方法があるかどうか疑問に思っています。
回答:
マニフェストで公開されているコンポーネントをアクティブにするかどうかを制御したいようですが、実行中に動的にレシーバーを(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();
}
onDestroy()
が呼び出されることは保証されていないため、メモリリークが発生する可能性があります。これは、/登録解除で登録する方が良いでしょうonStart()
/ onStop()
。
人々が言及することを忘れる1つの重要な点は、の寿命Broadcast Receiver
です。プログラムで登録することとAndroidManifest.xmlに登録することの違いはそれです。マニフェストファイルでは、アプリケーションの寿命に依存しません。プログラムで登録する場合は、アプリケーションの寿命に依存します。つまり、AndroidManifest.xmlに登録すると、アプリケーションが実行されていないときでも、ブロードキャストされたインテントをキャッチできます。
編集:上記のメモはAndroid 3.1以降は当てはまりません。対応するアプリケーションがユーザーによって起動されたことがない場合、またはユーザーが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
}
};
IntentFilterを onCreate()
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フィルタを)詳細は。
context.registerReceiver
が、呼び出されませんでした。この質問をご覧ください。stackoverflow.com
受信者を登録するときは常に許可を与えることがベストプラクティスです。そうしないと、一致するインテントを送信するアプリケーションで受信されます。これにより、悪意のあるアプリが受信機にブロードキャストする可能性があります。
以下のための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)アクティビティが表示されているときにのみブロードキャストを読みたい場合は、
registerReceiver(...
)内onStart()
および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);