BroadcastReceiver是什么
BroadcastReceiver 是Android四大组件之一,意为“广播接受者”,主要是用来接收系统的广播或者我们自定义的广播。
系统广播
系统广播是由系统发出的,我们只需要注册即可,例如开机完成后会发送开机广播android.intent.action.BOOT_COMPLETED ,我们就可以在需要开机自启动的应用程序中注册这个广播。手机电量过低会发送广播ACTION_BATTERY_LOW,收到这个广播后可以进行充电提示,还有其他很多系统广播,大家在需要时可以直接注册使用。(注意有些系统广播还要同时注册权限,如注册开机广播同时要添加权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> )
自定义广播
自定义广播需要注册广播接收者,同时需要发送这个自定义的广播。
如何使用广播
1、注册广播,注册广播分为两种,静态注册和动态注册。
静态注册是在AndroidManifest.xml文件中定义<reciver android:name=“”/>标签,注意这样注册的广播应用程序不启动也可以接收到。
动态注册是在程序中使用Context.registerReceiver注册,注册的广播接收器相当于一个匿名类。
2、发送广播,Context.sendBroadcast发送广播。
3、接收广播事件,当发送的广播被接收器监听到后,会调用它的onReceive()方法,并将包含消息的Intent对象传给它。注意:当BroadcastReceiver在10秒内没有执行完毕,Android会认为该程序无响应,所以在 BroadcastReceiver里不能做一些比较耗时的操作,否则会弹出ANR(Application No Response)的对话框。
BroadCastReceive的生命周期
onReceive方法返回后,对象就消失了,当下次再发送广播,则会再次生成receiver对象。
静态注册系统广播
这里我们注册一个开机广播
public class BootCompletedReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) { Log.i("MainActivity", "开机完毕"); } }
|
在AndroidManifest.xml文件中进行注册:
<receiver android:name=".BootCompletedReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> |
添加所需要的权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> |
静态注册自定义广播
定义广播接收类
public class MyBroadcastReciver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // 这里用来处理接收到的广播事件 Log.i("onReceive",intent.getAction()); } } |
在AndroidManifest.xml中注册自定义Action
<receiver android:name="com.example.broadcastreciverdemo.MyBroadcastReciver"> <intent-filter > <action android:name="com.example.broadcastreciver.MyBroadcast"/> </intent-filter> </receiver> |
发送广播
public class MainActivity extends Activity { private final String broadcastAction = "com.example.broadcastreciver.MyBroadcast"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent broadcastIntent = new Intent(); broadcastIntent.setAction(broadcastAction); //发送自定义广播 sendBroadcast(broadcastIntent); } } |
打印出log,收到自定义广播
动态注册自定义广播
这种广播不是常驻的,会跟随程序的生命周期而存在。
public class MainActivity extends Activity { private Button sendBroadCast; private final String broadcastAction = "com.example.broadcastreciver.MyBroadcast"; IntentFilter filter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendBroadCast = (Button)findViewById(R.id.button1); sendBroadCast.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent i = new Intent(); i.setAction(broadcastAction); //发送广播 sendBroadcast(i); } }); } @Override protected void onResume() { super.onResume(); //创建过滤器 filter = new IntentFilter(); filter.addAction(broadcastAction); //注册广播 registerReceiver(myReceiver,filter); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); //解除注册 unregisterReceiver(myReceiver); } //用匿名类创建一个广播接收器对象 BroadcastReceiver myReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { Log.i("onReceive", intent.getAction()); } }; } |
收到广播
有序广播
一般的广播对于多个接收者来说是完全异步的,每个接收者都无需等待就可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的接收动作。
有序广播比较特殊,它每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者可以终止这个广播。
首先定义三个广播接收器:
发送有序广播的方法为sendOrderedBroadcast()。优先接收到Broadcast的接收者可以通过setResultExtras(Bundle)方法将处理结果存入Broadcast中,然后传给下一个接收者下一个接收者通过Bundle bundle = new getResultExtras(true)可以获取上一个接收者存入的数据。
MyFirstReceiver.java
public class MyFirstReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // 这里用来处理接收到的广播事件 String message = intent.getStringExtra("message"); Log.i("onReceive","firstReceiver "+intent.getAction()); Bundle bundle = new Bundle(); bundle.putString("message", message + "+MyFirstReceiver"); setResultExtras(bundle); } } |
MySecondReceiver .java
public class MySecondReceiver extends BroadcastReceiver{
@Override public void onReceive(Context context, Intent intent) { // 这里用来处理接收到的广播事件 String message = getResultExtras(true).getString("message"); Log.i("onReceive","SecondReceiver "+intent.getAction()+message); Bundle bundle = new Bundle(); bundle.putString("message", message + "+MySecondReceiver"); setResultExtras(bundle); } } |
MyThirdReceiver .java
public class MyThirdReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // 这里用来处理接收到的广播事件 String message = getResultExtras(true).getString("message"); Log.i("onReceive","ThirdReceiver "+intent.getAction()+message); } } |
声明接收器:
在androidmanifest.xml文件中声明这三个接收器,并给它们注册相同的Action,有序广播中有一个设定接收优先级的属性android:priority 数字越大优先级越高.取值范围为-1000~1000,先可以在代码中调用IntentFilter对象的setPriority()进行设置.
<receiver android:name="com.example.broadcastreciverdemo.MyFirstReceiver"> <intent-filter android:priority="3"> <action android:name="com.example.broadcastreciver.MyBroadcast"/> </intent-filter> </receiver> <receiver android:name="com.example.broadcastreciverdemo.MySecondReceiver"> <intent-filter android:priority="2"> <action android:name="com.example.broadcastreciver.MyBroadcast"/> </intent-filter> </receiver> <receiver android:name="com.example.broadcastreciverdemo.MyThirdReceiver"> <intent-filter android:priority="1"> <action android:name="com.example.broadcastreciver.MyBroadcast"/> </intent-filter> </receiver> |
发送有序广播
public class MainActivity extends Activity { private Button sendBroadCast; private final String broadcastAction = "com.example.broadcastreciver.MyBroadcast"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendBroadCast = (Button)findViewById(R.id.button1); sendBroadCast.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent i = new Intent(); i.setAction(broadcastAction); i.putExtra("message", "sendOrderBroadcast"); //发送广播 sendOrderedBroadcast(i,"com.permisson.myOrderBroadcastPermisson"); } }); } } |
注意,使用sendOrderedBroadcast(Intent i, String s)方法发送有序广播时,其中第二个参数是指定接收者必须拥有的接收权限需要一个权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。
在androidmanifest.xml中声明权限
<permission android:protectionLevel="normal" android:name="com.permisson.myOrderBroadcastPermisson"></permission> |
使用权限
<uses-permission android:name="com.permisson.myOrderBroadcastPermisson"/> |
运行结果:
如果要终止广播传送,只需要在onReceive方法中加入abortBroadcast();
public class MyFirstReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // 这里用来处理接收到的广播事件 String message = intent.getStringExtra("message"); Log.i("onReceive","firstReceiver "+intent.getAction()); Bundle bundle = new Bundle(); bundle.putString("message", message + "+MyFirstReceiver"); setResultExtras(bundle); abortBroadcast(); } } |
运行结果,广播传递被终止
sendStickyBroadcast
sendStickyBroadcast()发出的广播会一直滞留(等待),以便有人注册这则广播消息后能尽快的收到这条广播。其他功能与sendBroadcast相同。但是使用sendStickyBroadcast 发送广播需要获得BROADCAST_STICKY 权限。
首先主Activity,三个按钮,分别发送两种广播和进行跳转。
操作步骤,点击两个发送广播按钮,然后跳转到ReceiveActivity,可以发现两者的区别。
MainActivity.java
public class MainActivity extends Activity implements OnClickListener { //普通发送方式 private final String broadcastAction = "com.example.broadcastreciver.MyBroadcast"; //sticky发送方式 private final String stickyBroadcastAction = "com.example.broadcastreciver.MyStickyBroadcast"; private Button sendBroadCast; private Button sendStickyBroadCast; private Button goReceiveActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendBroadCast = (Button)findViewById(R.id.broadcastBtn); sendStickyBroadCast = (Button)findViewById(R.id.stickyBtn); goReceiveActivity = (Button)findViewById(R.id.goReceiveActivity);
sendBroadCast.setOnClickListener(this); sendStickyBroadCast.setOnClickListener(this); goReceiveActivity.setOnClickListener(this); } @Override public void onClick(View v) { int id = v.getId(); switch (id) { case R.id.broadcastBtn: Intent intentBroadcast = new Intent(); intentBroadcast.setAction(broadcastAction); //发送普通广播 sendBroadcast(intentBroadcast); break; case R.id.stickyBtn: Intent stickyBroadcast = new Intent(); stickyBroadcast.setAction(stickyBroadcastAction); //发送普通广播 sendStickyBroadcast(stickyBroadcast); break; case R.id.goReceiveActivity: Intent goReceive = new Intent(MainActivity.this,ReceiveActivity.class); startActivity(goReceive); break; default: break; } } } |
ReceiveActivity.java
public class ReceiveActivity extends Activity { private final String broadcastAction = "com.example.broadcastreciver.MyBroadcast"; private final String stickyBroadcastAction = "com.example.broadcastreciver.MyStickyBroadcast"; IntentFilter filter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_receive); } @Override protected void onResume() { super.onResume(); filter = new IntentFilter(); //注册一般的广播action filter.addAction(broadcastAction); //注册sticky广播的action filter.addAction(stickyBroadcastAction); registerReceiver(receiver, filter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); } BroadcastReceiver receiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { Log.i("onReceive",intent.getAction()); } }; } |
注册权限
<uses-permission android:name="android.permission.BROADCAST_STICKY"/> |
运行结果为:
可以发现,sendBroadCast发送的广播没有接收到,而sendStickyBroadcast()方法发送的广播接收到了,说明了它的延时性。