我想知道以编程方式注册广播接收器的最佳实践/方式是什么。我想根据用户选择注册特定的接收器。

通过清单文件完成注册,我想知道是否有适当的方法可以在代码中实现此目标。

评论

CoderzPassion Broadcast Receiver最好的详细教程
请参考此链接stackoverflow.com/questions/15698790/…

#1 楼

听起来您想控制清单中发布的组件是否处于活动状态,而不是在运行时动态地注册接收者(通过Context.registerReceiver())。如果是这样,则可以使用PackageManager.setComponentEnabledSetting( )来控制这些组件是否处于活动状态:

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

请注意,如果您只对在运行时接收广播感兴趣,则最好使用registerReceiver()。接收器组件主要用于需要确保每次发送广播时都启动应用程序的应用程序。

评论


聪明!你让我直率。非常感谢你

–CoolStraw
2011年1月26日15:15

好人-不知道您可以这样做:)

–克里斯·诺尔德斯(Chris Noldus)
2014年1月29日在21:31

它类似于stackoverflow.com/questions/24140894/…

– Ankit Srivastava
2014年6月10日12:59

@hackbod如何在自定义接收器中添加元数据标签?你有什么想法!我需要添加我们在androidmanifest.xml中使用的元数据标签。

– Zala Janaksinh
15年5月9日在6:20



到目前为止最好的教程coderzpassion.com/implement-broadcastreceiver-android和简单语言

–贾格吉特·辛格(Jagjit Singh)
17年6月27日在5:16

#2 楼

在您的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方法中运行它: >

评论


谢谢,这很好。为了发送广播,我使用了代码Intent i = new Intent(“ SOME_ACTION”); sendBroadcast(i);

–本·克莱顿
2011年4月7日在15:08

为什么不在简历和开始时加入?

–赛义德·拉扎·梅迪(Syed Raza Mehdi)
15年4月15日在4:47

如果我不注销广播接收器将会怎样?即使重新启动后,广播接收器也会保持注册状态吗?

– Jaydev
16年11月15日在4:38

无法保证onDestroy()会被调用,从而造成潜在的内存泄漏。最好在onStart()/ onStop()中进行注册/注销。

– Neria Nachum
17年1月26日在10:53



这是否意味着我不必创建广播接收器类?我可以将所有的onReceive()代码放在这里,这样行得通吗?

– Taslim Oseni
17/12/22在12:07

#3 楼

人们忘记提及的重要一点是Broadcast Receiver的使用寿命。以编程方式注册它与在AndroidManifest.xml中注册的区别在于。在清单文件中,它不依赖于应用程序生存时间。以编程方式注册时,它的确取决于应用程序的寿命。这意味着,如果您在AndroidManifest.xml中进行注册,即使您的应用程序未运行,您也可以捕获广播的意图。

编辑:从Android 3.1(即Android系统)开始,上述注释不再适用如果用户从未启动过相应的应用程序,或者用户通过Android菜单(在“管理”→“应用程序”中)明确停止了该应用程序,则默认情况下将所有接收者排除在接收意图之外。 https://developer.android.com/about/versions/android-3.1.html

这是一项附加的安全功能,因为用户可以确保只有他启动的应用程序才能收到广播意图。

因此可以理解为,以编程方式在Application的onCreate()中注册的接收者与从Android 3.1以上的AndroidManifest.xml中声明的接收者具有相同的效果。

评论


这是一个很好的笔记。我实际上正在看一本我正在阅读的有关android的书,想知道为什么两种实现广播的方法都已经完成。在我看来,这确实是为了向后兼容。但是我不确定。

–霓虹灯Warge
15年2月17日在15:46

好吧,您真的认为修改是正确的吗?我的意思是最后一句话。 Android可能会随时杀死您的应用程序,这将导致您以编程方式注册的接收器不再起作用,但已注册的清单仍将起作用。

–JacksOnF1re
16年5月24日在12:22

#4 楼

在“活动” /“片段”中的任何地方定义广播接收器,如下所示:

mReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
     Log.d(TAG," onRecieve"); //do something with intent
   }
 };


onCreate()中定义IntentFilter
现在,在onResume()中注册BroadcastReciever,然后在onPause()中取消注册[因为如果活动被暂停,则不会使用广播]。

mIntentFilter=new IntentFilter("action_name");


有关详细教程,请查看广播接收器-两种实现方式。

评论


到目前为止,我发现了最好的例子!谢谢!

–阿育斯·戈亚尔
13年5月8日在10:41

@SohailAziz链接提供了一个很好的答案。您能否将链接的上下文放在答案中,以便如果链接断开,您的答案仍然有意义?

– iRuth
15年2月28日在8:20

在我个人看来,广播应该按照您的建议在onResume和onPause中进行注册,但是有人说广播必须在onCreate和onDestroy上,您能解释两者的优缺点吗?

–赛义德·拉扎·梅迪(Syed Raza Mehdi)
15年4月15日在4:49

@SyedRazaMehdi,如果使用广播来更新UI(在大多数情况下),则应在onResume中注册它,并在onPause中取消注册,因为否则广播将无用。

– SohailAziz
15年4月17日在22:36

谢谢。这是最好的答案。

–Saeid Z
19年8月5日在14:07

#5 楼

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


评论


您能否向OP解释为什么这是最佳做法?

–马丁·普里克里(Martin Prikryl)
2013年6月1日12:48在

他们不解释,“他们”总是张贴代码,因为您知道它要好得多。 -讽刺

–霓虹灯Warge
17-2-14在4:54

#6 楼

根据在Android中侦听和广播全局消息以及在常见任务中设置警报以及如何执行警报:


如果接收类未在其
中注册<清单,您可以通过
调用Context.registerReceiver()来动态地实例化并注册接收器。 IntentFilter过滤器)以获取更多信息。

评论


我试过调用context.registerReceiver,但没有被调用,请您看一下这个问题stackoverflow.com/questions/13238600/…

–狩猎
2012年11月6日18:10

#7 楼

最佳实践是在注册接收者时始终提供许可,否则,对于发送匹配意图的任何应用程序,您都会收到许可。这可以允许恶意应用广播到您的接收器。

#8 楼

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


#9 楼

两种选择


1)如果只想在活动可见的情况下阅读广播
,则请在registerReceiver(...中阅读
onStart()中的unregisterReceiver(...)


2)如果即使活动处于后台,您仍要阅读广播,则


onStop()中的registerReceiver(...)onCreate(...)

奖励:


如果您很懒惰


如果您不想在每个Activity中编写用于反复注册和注销BroadcastReceiver的样板代码,然后


创建抽象Activity
在Activity中写样板代码
将实现保留为抽象方法

这是代码段:


抽象活动


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

}


>
使用这种方法,您可以编写更多样板代码,例如
编写常见动画,绑定到服务等。


查看完整代码:

这里

#10 楼

创建广播接收器

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