web-dev-qa-db-ja.com

放送受信機をプログラムで登録する

放送受信機をプログラムで登録するベストプラクティス/方法を教えてください。ユーザーの選択に従って特定のレシーバーを登録したい。

登録はマニフェストファイルを介して行われるため、コードでこれを実現する適切な方法があるかどうか疑問に思っています。

138
CoolStraw

マニフェストで公開されたコンポーネントがアクティブであるかどうかを制御したいようですが、実行中に(Context.registerReceiver()を介して)レシーバーを動的に登録します。

その場合、PackageManager.setComponentEnabledSetting()を使用して、これらのコンポーネントがアクティブかどうかを制御できます。

http://developer.Android.com/reference/Android/content/pm/PackageManager.html#setComponentEnabledSetting(Android.content.ComponentName、int、int)

実行中にブロードキャストの受信のみに関心がある場合は、registerReceiver()を使用することをお勧めします。レシーバーコンポーネントは、ブロードキャストが送信されるたびにアプリが起動されるようにする必要がある場合に主に役立ちます。

64
hackbod

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();
 }
256
Eric Nordvik

人々が言及することを忘れている重要な点の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で宣言されたレシーバーと同じ効果があると理解できます。上記。

66
Krypton

次のように、アクティビティ/フラグメントの任意の場所にブロードキャストレシーバーを定義します。

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つの方法 をご覧ください。

36
SohailAziz
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();
   }
}
4
Sunil Pandey

受信者を登録するときは常に許可を与えるのがベストプラクティスです。そうしないと、一致するインテントを送信するアプリケーションに対して受信します。これにより、悪意のあるアプリが受信者にブロードキャストできるようになります。

2
ChopperCharles

グローバルメッセージのリッスンとブロードキャスト、および 一般的なタスクでのアラームの設定とAndroidでのそれらの実行方法 によると:

マニフェストで受信クラスが登録されていない場合、Context.registerReceiver()を呼び出すことにより、受信側を動的にインスタンス化して登録できます。

詳細については、 registerReceiver(BroadcastReceiverレシーバー、IntentFilterフィルター)を参照してください

2
McStretch

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
Xar E Ahmer

2つの選択肢

1)アクティビティが表示されているときにのみブロードキャストを読みたい場合、

onStart()registerReceiver(...およびunregisterReceiver(...)onStop()

2)アクティビティがバックグラウンドにある場合でもブロードキャストを読みたい場合は、

registerReceiver(...)onCreate(...)およびunregisterReceiver(...)onDestroy()

ボーナス:

あなたが怠け者なら

各アクティビティでBroadcastReceiverを何度も登録および登録解除するための定型コードを記述したくない場合は、

  1. 抽象アクティビティを作成する
  2. アクティビティで定型コードを書く
  3. 実装を抽象メソッドのままにします

ここにコードスニペットがあります:

抽象アクティビティ

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();

}

このアプローチを使用すると、一般的なアニメーションの作成、サービスへのバインドなど、より定型的なコードを作成できます。

完全なコードを見る:

ここ

1
Rohit Singh

ブロードキャストレシーバーの作成

[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);
0
fulgen