由于注册是通过清单文件完成的,因此我想知道是否有适当的方法在代码中实现这一点。
你可以在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();
}
onDestroy()
一定会被调用,因此可能会导致内存泄漏。更好的做法是在onStart()
/onStop()
中注册/取消注册。 - Neria Nachum有一个重要的点,人们经常遗忘提及 Broadcast Receiver
的生命周期。通过程序注册和在 AndroidManifest.xml 注册的区别在于,在清单文件中,它不依赖于应用程序的生命周期。而当以编程方式进行注册时,则会依赖于应用程序的生命周期。这意味着,如果您在 AndroidManifest.xml 中注册,即使您的应用程序没有运行,也可以捕获广播的意图。
编辑:截至 Android 3.1,上述注释不再适用,如果相应的应用程序从未被用户启动或者用户通过 Android 菜单(在 Manage → Application 中)明确停止了该应用程序,则 Android 系统默认排除所有接收器接收意图。https://developer.android.com/about/versions/android-3.1.html
这是一个附加的安全功能,因为用户可以确信只有他启动的应用程序将接收广播意图。
因此,可以理解为在 onCreate()
中以编程方式注册的接收器与从 Android 3.1 开始在 AndroidManifest.xml 中声明的接收器具有相同的效果。
看起来您想要控制在清单中发布的组件是否活动,而不是在运行时通过Context.registerReceiver()动态注册接收器。
如果是这样的话,您可以使用PackageManager.setComponentEnabledSetting()方法来控制这些组件是否活动:
请注意,如果您只对在运行时接收广播感兴趣,最好使用registerReceiver()方法。接收器组件主要用于确保每次发送广播时都启动您的应用程序。
Define a broadcast receiver anywhere in Activity/Fragment like this:
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();
}
}
1) 如果您想在Activity可见时才读取广播,则在
onStart()
中调用registerReceiver(...)
,并在onStop()
中调用unregisterReceiver(...)
2) 如果您想即使Activity在后台也要读取广播,则在
onCreate(...)
中调用registerReceiver(...)
,并在onDestroy()
中调用unregisterReceiver(...)
如果您懒得写重复的注册和注销BroadcastReceiver的样板代码,那么可以:
以下是代码片段:
抽象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();
}
使用这种方法,您可以编写更多的样板代码,例如编写常见的动画,绑定到服务等。
关于 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")
<receiver>
注册,则可以通过调用Context.registerReceiver()来动态实例化和注册接收器。
更多信息请参见registerReceiver(BroadcastReceiver receiver, IntentFilter filter)。
context.registerReceiver
但它没有被调用,你能否看一下这个问题:https://dev59.com/ImrWa4cB1Zd3GeqP_XvI - Hunt在注册接收器时,最好始终提供权限,否则您将接收到发送匹配意图的任何应用程序。这可能会使恶意应用程序广播到您的接收器。
创建广播接收器
[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);