プログラムでブロードキャストレシーバーを登録する


149

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

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


2
CoderzPassion Broadcast Reciever史上最高の詳細なチュートリアル
karanatwal.github.io 2017年

このリンクを参照してください stackoverflow.com/questions/15698790/...

回答:


64

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

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

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

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


1
賢い!あなたは私をまっすぐにしました。どうもありがとうございました
CoolStraw 2011年

いいね
Chris Noldus 14年


1
@hackbodカスタムレシーバーにメタデータタグを追加するにはどうすればよいですか?あなたは何か考えがあります!! androidmanifest.xmlで使用するメタデータタグを追加する必要があります。
Zala Janaksinh

1
日付までの最高のチュートリアルcoderzpassion.com/implement-broadcastreceiver-androidとシンプルな言語
Jagjit Singh

269

あなたの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();
 }

19
ありがとう、これはうまくいきました。ブロードキャストを送信するには、コードIntent i = new Intent( "SOME_ACTION");を使用しました。sendBroadcast(i);
Ben Clayton

7
なぜ、再開時と開始時ではないのですか?
Syed Raza Mehdi 2015

放送受信機の登録を解除しないとどうなりますか?再起動後も、放送受信機を登録したままにしますか?
Jaydev 2016年

5
onDestroy()が呼び出されることは保証されていないため、メモリリークが発生する可能性があります。これは、/登録解除で登録する方が良いでしょうonStart()/ onStop()
Neria Nachum 2017年

これは、ブロードキャストレシーバークラスを作成する必要がないことを意味しますか?すべてのonReceive()コードをここに置くだけでうまくいきますか?
Taslim Oseni 2017

70

人々が言及することを忘れる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で宣言されたレシーバーと同じ効果を持つと理解できます。


1
これは良いメモです。私は実際に私がアンドロイドについて読んでいる本を見ていて、なぜブロードキャストを実装する2つの方法の両方が行われたのかと思っています。それは後方互換性のためであるように私には思えます。しかし、私にはわかりません。
ネオンワージ2015

さて、あなたは本当に編集が本当であるということですか?私は最後の文を意味します。Androidはいつでもアプリケーションを強制終了する可能性が高いため、プログラムで登録されたレシーバーが機能しなくなりますが、登録されたマニフェストは引き続き機能します。
JacksOnF1re 2016年

40

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

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


これまでに見つけた最良の例!ありがとう!
Ayush Goyal 2013年

1
@SohailAzizリンクは良い答えを提供します。リンクのコンテキストを回答に含めて、リンクがダウンしても、回答の関連性を維持できますか?
iRuth 2015

私の個人的な見解では、ブロードキャストはあなたが提案したようにonResumeとonPauseに登録する必要がありますが、一部の人々はonCreateとonDestroyにある必要があると言いますが、両方の長所と短所を説明できますか?
Syed Raza Mehdi、2015

2
@SyedRazaMehdiブロードキャストを使用してUIを更新する場合(ほとんどの場合)、それをonResumeに登録し、onPauseで登録解除する必要があります。そうしないと、ブロードキャストが役に立たなくなるためです。
SohailAziz、2015

ありがとう。これが最良の答えです。
Saeid Z

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

1
これがベストプラクティスである理由をOPに説明してもらえますか?
Martin Prikryl 2013年

1
彼らは説明しません。「彼らは」常にコードを投稿します。-sarcasm
ネオンWarge

2

・放送・グローバル・メッセージをリッスンし、中にアラームを設定するによると、一般的なタスクとどのようにAndroidのでそれらを実行するには

受信クラスがマニフェストでを使用して登録されていない場合は、Context.registerReceiver()を呼び出して、レシーバーを動的にインスタンス化して登録できます。

見てみましょうregisterReceiver(BroadcastReceiver受信機、IntentFilterフィルタを)詳細は。


1
呼び出してみましたcontext.registerReceiverが、呼び出されませんでした。この質問をご覧ください。stackoverflow.com
Hunt

2

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


1

以下のための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

2つの選択肢

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

registerReceiver(...)内onStart()および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();

}

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

完全なコードを見る:

ここに


0

放送受信機を作成する

[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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.