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

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

由于注册是通过清单文件完成的,因此我想知道是否有适当的方法在代码中实现这一点。

227103 次浏览

根据监听和广播全球信息,并在 Android 中的常见任务及其实现方法中设置警报:

如果接收类不是 注册使用 清单,您可以动态地 通过实例化和注册接收器 呼叫 RegisterReceiver ()

看看 Register 接收器(BroadcastReceiver 接收器,意图过滤器)了解更多信息。

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

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

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

Http://developer.android.com/reference/android/content/pm/packagemanager.html#setcomponentenabledsetting (android.content. Component entName,int,int)

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

像下面这样在活动/片段中的任何地方定义一个广播接收器:

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

onCreate()中定义意图过滤器

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的寿命。以编程方式注册它与在 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中声明的接收器具有相同的效果。

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

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

本地广播经理

   Intent intent = new Intent("any.action.string");
LocalBroadcastManager.getInstance(context).
sendBroadcast(intent);

onResume注册

LocalBroadcastManager.getInstance(
ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);

取消注册

LocalBroadcastManager.getInstance(
ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);

接受它。

mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("mBroadcastReceiver", "onReceive");
}
};

意图过滤器在哪里

 new IntentFilter("any.action.string")

创建广播接收器

[ BroadcastReceiver (启用 = true,导出 = false)]

public class BCReceiver : BroadcastReceiver
{


BCReceiver receiver;


public override void OnReceive(Context context, Intent intent)
{
//Do something here
}
}

从你的活动中添加以下代码:

LocalBroadcastManager.getInstance(ApplicationContext)
.registerReceiver(receiver, filter);

两个选择

1)如果你只想在活动可见的时候阅读“广播” 那么,

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

2)如果你想阅读广播,即使活动是在背景中 那么,

onCreate(...)中的 registerReceiver(...)onDestroy()中的 unregisterReceiver(...)

意外收获:

如果你懒惰

如果您不想编写样板代码,以便在每个 Activity 中一次又一次地注册和注销 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();


}

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

见完整代码:

给你