[英]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()来控制这些组件是否处于活动状态:
请注意,如果您只对在运行时接收广播感兴趣,最好使用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,那么,
这是代码片段:
抽象活动
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.