簡體   English   中英

以編程方式注冊廣播接收器

[英]Programmatically register a broadcast receiver

我想知道以編程方式注冊廣播接收器的最佳實踐/方法是什么。 我想根據用戶的選擇注冊特定的接收器。

由於注冊是通過清單文件完成的,我想知道是否有一種正確的方法可以在代碼中實現這一點。

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

人們忘記提到的一個重點是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中聲明的接收器具有相同的效果。

聽起來您想要控制清單中發布的組件是否處於活動狀態,而不是在運行時動態注冊接收器(通過Context.registerReceiver())。

如果是這樣,您可以使用PackageManager.setComponentEnabledSetting()來控制這些組件是否處於活動狀態:

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

請注意,如果您只對在運行時接收廣播感興趣,最好使用registerReceiver()。 接收器組件主要用於在每次發送廣播時確保啟動應用程序的情況。

在Activity / Fragment中的任意位置定義廣播接收器,如下所示:

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

現在在onResume()注冊BroadcastReciever並在onPause()取消注冊[因為如果活動暫停,則不使用廣播]。

@Override
protected void onResume() {
     super.onResume();
     registerReceiver(mReceiver, mIntentFilter);
}

@Override
protected void onPause() {
    if(mReceiver != null) {
            unregisterReceiver(mReceiver);
            mReceiver = null;
    }
    super.onPause();
}

有關詳細教程,請查看廣播接收器 - 兩種實現方式

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)如果您只想在活動可見時閱讀廣播,那么,

registerReceiver(... )的onStart()unregisterReceiver(...)onStop()

2)如果你想閱讀廣播,即使活動在后台,那么,

registerReceiver(...)onCreate(...)unregisterReceiver(...)onDestroy()

獎金:

如果你很懶

如果你不想編寫樣板代碼來在每個Activity中反復注冊和取消注冊BroadcastReceiver,那么,

  1. 創建一個抽象活動
  2. 在Activity中編寫樣板代碼
  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();

}

使用這種方法,您可以編寫更多樣板代碼,例如編寫常用動畫,綁定到服務等。

查看完整代碼:

這里

創建廣播接收器

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM