Android中的广播主要可以分为两种类型:标准广播和有序广播。
一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时间接收到这条广播,因此他们之间没有任何的先后顺序。
特点:效率高;缺点:无法拦截。
一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够接收到这条广播,当该广播接收器执行完OnReceive()方法逻辑后,广播才会继续传递。
特点:优先级高者会先接收到广播,并且可以拦截该条广播是否继续传递。
1,监听手机是否插入耳机广播(动态注册)
注册代码
intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.HEADSET_PLUG");
registerReceiver(myBrodcast, intentFilter);
Toast.makeText(this, "监听耳机广播已注册", Toast.LENGTH_SHORT).show();
广播接收器代码
class MyBrodcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (null != intent) {
String action = intent.getAction();
switch (action) {
case "android.intent.action.HEADSET_PLUG":
if (intent.hasExtra("state")) {
if (intent.getIntExtra("state", 0) == 0) {
Log.e(TAG, "headset not connected");
} else if (intent.getIntExtra("state", 0) == 1) {
Log.e(TAG, "headset connected");
}
}
break;
}
}
}
}
运行插入耳机、拔出耳机Log打印:
注册代码
intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF); // 必须代码来注册
intentFilter.addAction(Intent.ACTION_SCREEN_ON); // 必须代码注册
// intentFilter.addAction(Intent.ACTION_USER_PRESENT); // 可以静态注册
registerReceiver(bootCompleteReceiver, intentFilter);
Toast.makeText(this, "锁屏解锁广播已注册", Toast.LENGTH_SHORT).show();
xml
<receiver
android:name=".receiver.BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT"/>
intent-filter>
receiver>
广播接收器
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
if (null != intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.e(TAG, "手机开屏");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.e(TAG, "手机锁屏");
} else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Log.e(TAG, "手机解锁");
}
}
}
运行效果图
注册代码
<receiver android:name=".receiver.MyBrodcast">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
intent-filter>
receiver>
接收器代码
case "android.intent.action.BOOT_COMPLETED":
Log.e(TAG, "手机已开机");
break;
- 发送自定义广播
上面讲的都是系统广播,系统广播需要注册;而自定义广播则需要人为发送。
一般情况使用自定义广播来实现某个功能,下面就来看个例子:接收到自定义广播后,启动一个界面。
注册代码
<receiver android:name=".receiver.MyBrodcast">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="com.example.mu16jj.broadcastreceiver">action>
intent-filter>
receiver>
直接使用前面的广播接收器了,在这里增加一个自定义的 action。
点击注册代码
Intent intent = new Intent("com.example.mu16jj.broadcastreceiver");
sendBroadcast(intent);
接收器代码
case "com.example.mu16jj.broadcastreceiver":
Log.e(TAG, "我是自定义的");
// 在广播接收器中打开Activity
Intent inten = new Intent(context, MainActivity.class);
inten.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(inten);
break;
运行后Log
- 发送有序广播
发送方式由原来的 sendBroadcast(intent) 改变为 sendOrderedBroadcast(intent, null),不同的应用注册同一个广播,那么这两个(或者更多)都是可以接收到这条广播的。
既然是有序广播,那么这个顺序的确定就由有一个属性来确定,例如:
<intent-filter android:priority="100">
priority 数越大优先级别越高,最大值是2147483647;优先级别也可以调用 IntentFilter 对象的 setPriority() 方法进行设置。
当然也可以拦截,只需要在广播接收器的 onReceive() 方法中调用下面一句代码就可以实现:
abortBroadcast();
使用本地广播
上面的有序广播提到了不同的应用可以相互接受广播,那么就存在一个安全问题,为此,Android 系统为我们提供了本地广播管理器类 LocalBroadcastManager,使用它来负责应用中的广播发送,就相对安全多了,实例化方式:
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
当然了,既然是管理器,那么发送和取消就自然由它负责。
以上的测试手机版本为5.1.1,如果在较高版本运行出现关于动态权限问题,需要自己手动处理。
还在持续更新中…
推荐专题《Android开发资源经验分享》《Android面试专辑》
QQ交流群:481794398