以编程方式注册广播接收器

时间:2011-01-26 13:50:27

标签: android broadcastreceiver

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

由于注册是通过清单文件完成的,我想知道是否有一种正确的方法可以在代码中实现这一点。

10 个答案:

答案 0 :(得分:255)

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

答案 1 :(得分:66)

人们忘记提及的一个重点是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 中声明的接收器具有相同的效果。

答案 2 :(得分:64)

听起来您想要控制清单中发布的组件是否处于活动状态,而不是在运行时动态注册接收器(通过Context.registerReceiver())。

如果是这样,您可以使用PackageManager.setComponentEnabledSetting()来控制这些组件是否处于活动状态:

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

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

答案 3 :(得分:36)

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

有关详细教程,请查看broadcast receiver-two ways to implement

答案 4 :(得分: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();
   }
}

答案 5 :(得分:2)

根据倾听和广播全球消息,以及Common Tasks and How to Do Them in Android中的设置警报:

  

如果接收类不是   在其中注册使用   清单,你可以动态   通过实例化和注册接收器   调用 Context.registerReceiver()

请查看registerReceiver (BroadcastReceiver receiver, IntentFilter filter)了解详情。

答案 6 :(得分:2)

最佳做法是在注册接收方时始终提供权限,否则您将收到任何发送匹配意图的应用程序。这可以允许恶意应用程序广播到您的接收器。

答案 7 :(得分: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")

答案 8 :(得分:1)

两个选择

  

1)如果您只想在活动可见时阅读广播   然后,

{p}中的

registerReceiver(...onStart()中的unregisterReceiver(...)

  

2)如果即使活动处于后台也要阅读广播   然后,

{{1}中的onStop()registerReceiver(...)中的onCreate(...)

奖金:

  

如果你很懒

如果您不想编写用于在每个Activity中一次又一次地注册和取消注册BroadcastReceiver的样板代码,

  1. 创建抽象活动
  2. 在活动中编写样板代码
  3. 将实现保留为抽象方法

以下是代码段:

  

抽象活动

unregisterReceiver(...)
  

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

查看完整代码:

HERE

答案 9 :(得分: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);