Android-BroadcastReceiver详解
什么是Broadcast
Broadcast即广播,在Android广播是非常重要的功能。例如我们想在系统开机之后做某些事情、监控手机的电量、监控手机的网络状态等等,这些功能都需要用到广播。当然我们也可以自定义广播。
自定义广播
通常实现一个简单的自定义广播可以通过如下几个步骤:
创建一个类继承android.content.BroadcastReceiver,并实现onReceive方法 在AndroidManifest.xml中注册广播 通过Context的registerReceiver等方法注册广播 调用Context的sendBroadcast等方法发送广播,在onReceive方法中处理广播 调用Context的unregisterReceiver等方法注销广播我们通过代码来解释一下上面的步骤:
1.创建一个类继承android.content.BroadcastReceiver,并实现onReceive方法
package com.mark.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 创建一个自定义广播接收者需要继承android.content.BroadcastReceiver,
* 并实现onReceive方法即可。
*/
public class MyReceiver extends BroadcastReceiver {
private final static String TAG = MyReceiver.class.getSimpleName();
public MyReceiver() {
}
/**
* 当接收到广播之后会调用此方法
* @param context 上下文对象
* @param intent 调用sendBroadcast(intent)传入的Intent实例,其中包含了action、和其他附带信息
*/
@Override
public void onReceive(Context context, Intent intent) {
// 获取msg对应的数据
String msg = intent.getStringExtra("msg");
// 打印msg数据
Log.i(TAG, "msg = " + msg);
// 打印action字符串
Log.i(TAG, "action = " + intent.getAction());
}
}
2.在AndroidManifest.xml中注册广播
3.通过Context的registerReceiver等方法注册广播
4.调用Context的sendBroadcast等方法发送广播,在onReceive方法中处理广播
5.调用Context的unregisterReceiver等方法注销广播
package com.mark.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
BroadcastReceiver registerReceiver;
IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建BroadcastReceiver实例
registerReceiver = new MyReceiver();
// 创建IntentFilter,指定其action为com.mark.broadcast.receiver,这个可以自己定义
intentFilter = new IntentFilter("com.mark.broadcast.receiver");
// 注册广播将registerReceiver与intentFilter关联,
// registerReceiver可以接收到action为com.mark.broadcast.receiver的广播
registerReceiver(registerReceiver, intentFilter);
findViewById(R.id.btnRegister).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 发送广播
// 创建Intent,指定其action为com.mark.broadcast.receiver,与registerReceiver关联的action一致
Intent intent = new Intent("com.mark.broadcast.receiver");
// 指定要发送的信息
intent.putExtra("msg", "Hello, a new message.");
sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(registerReceiver);
}
}
通过上述的步骤我们就实现了一个自定义广播,当我们点击Button在控制台中可以看到如下信息:
04-13 17:12:28.591 16882-16882/com.mark.broadcastreciver I/MyReceiver: msg = Hello, a new message.
04-13 17:12:28.591 16882-16882/com.mark.broadcastreciver I/MyReceiver: action = com.mark.broadcast.receiver
注册广播
注册广播的方式有两种:静态注册和动态注册。
静态注册
这种方法是在配置AndroidManifest.xml配置文件中注册,通过这种方式注册的广播为常驻型广播,也就是说如果应用程序关闭了,有相应事件触发,程序还是会被系统自动调用运行。例如:
动态注册
这种方法是通过代码在.Java文件中进行注册。通过这种方式注册的广播为非常驻型广播,即它会跟随Activity的生命周期,所以在Activity结束前我们需要调用unregisterReceiver(receiver)方法移除它。例如:
// 创建BroadcastReceiver实例
registerReceiver = new MyReceiver();
// 创建IntentFilter,指定其action为com.mark.broadcast.receiver,这个可以自己定义
intentFilter = new IntentFilter("com.mark.broadcast.receiver");
// 注册广播将registerReceiver与intentFilter关联,
// registerReceiver可以接收到action为com.mark.broadcast.receiver的广播
registerReceiver(registerReceiver, intentFilter);
注意:如果我们在Activity中注册了BroadcastReceiver,当这个Activity销毁的时候要主动撤销注册否则会出现异常。方法如下:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(registerReceiver);
}
广播的类型
Broadcast的类型有两种:普通广播和有序广播。
Normal broadcasts (普通广播)
Normal broadcasts是完全异步的可以同一时间被所有的接收者接收到。消息的传递效率比较高。但缺点是接收者不能讲接收的消息的处理信息传递给下一个接收者也不能停止消息的传播。多个普通广播设置相同的IntentFilter,则先注册的先收到广播。
Ordered broadcasts (有序广播)
Ordered broadcasts的接收者按照一定的优先级进行消息的接收。如:A,B,C的优先级依次降低,那么消息先传递给A,在传递给B,最后传递给C。优先级别声明在中,取值为[-1000,1000]数值越大优先级别越高。优先级也可通过filter.setPriority(10)方式设置。
另外Ordered broadcasts的接收者可以通过abortBroadcast()的方式取消广播的传播,也可以通过setResultData和setResultExtras方法将处理的结果存入到Broadcast中,传递给下一个接收者。然后,下一个接收者通过getResultData()和getResultExtras(true)接收高优先级的接收者存入的数据。
例如:
如上两个receiver我们分别设置为priority为999,和1000,及时MyReceiver是后注册的,但是其优先级比FirstReceiver高,则MyReceiver会先处理广播。
sendOrderedBroadcast 发送有序广播
sendOrderedBroadcast(intent, receiverPermission)方法接收两个参数,比普通广播的发送方式多了一个receiverPermission参数,这是一个String类型的参数,代表具有这个权限的Receiver才能处理收到此广播。如果为null则表明不要求接受者声明指定权限。我们来看一下具体的操作。
首先我们要自定义一个权限,例如:
然后我们要是当前的程序具有此权限:例