第二十九章 broadcast intent
Receiver
broadcast intent
不同于普通的intent, 它可以发送给多个接收者(BroadcastReceiver
)- 创建receiver
- 继承
BroadcastReceiver
类或创建该类对象 - 重写
onReceive()
方法
注册广播
- 在清单文件中声明
<receiver android:name="com.bignerdranch.android.photogallery.StartupReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".NotificationReceiver"
android:exported="false">
<intent-filter android:priority="-999">
<action
android:name="com.bignerdranch.android.photogallery.SHOW_NOTIFICATION"/>
</intent-filter>
</receiver>
- 添加相应的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
- 但由于Android 8.0 以上系统对广播进行了限制, 能动态就不静态注册
- 如果要静态注册, 就要:
指定intent.setComponentName(包名, Receiver的全路径名)
- 接收系统广播只能在25版本及以下(以上版本有一些豁免广播可以与JobSchedule一起使用)
- 通过
context.registerReceiver(receiver, filter, String broadcastPermission, scheduler)
注册
receiver
:是BroadcastReceiver对象
filter
: 是IntentFilter对象, 用来寻找匹配行为. 可以.addAction()
, .setPriority
来对其行为进行设置
scheduler
:一般传入null
broadcastPermission
: 自己设置的权限, 为了安全级别而设置. 其使用为:
1.声明并获取权限
2.定义常量并带入broadcastPermission
<permission android:name="com.bignerdranch.android.photogallery.PRIVATE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.bignerdranch.android.photogallery.PRIVATE"/>
public static final String PERM_PRIVATE =
"com.bignerdranch.android.photogallery.PRIVATE";
protectLevel
有四个等级:normal
, dangerous
, signature
, signatureOrsystem
- 通过
context.unregisterReceiver(receiver)
取消注册
public abstract class VisibleFragment extends Fragment {
private static final String TAG = "VisibleFragment";
@Override
public void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(PollService.ACTION_SHOW_NOTIFICATION);
getActivity().registerReceiver(mOnShowNotification, filter,
PollService.PERM_PRIVATE, null);
}
@Override
public void onStop() {
super.onStop();
getActivity().unregisterReceiver(mOnShowNotification);
}
}
BroadcastReceiver mOnShowNotification = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "canceling notification");
setResultCode(Activity.RESULT_CANCELED);
}
};
发送broadcast intent
- 广播后Receiver可以看做同时接收(但实际上不是, 接收的顺序无法预测)
- 无优先级, 不能拦截, 不能修改, 不能终止
- 在注册广播时就声明了优先级. 静态直接设置, 动态通过
Intent.setPriority
sendOrderedBroadcast(intent, 自己申明的权限, 最终结果接受者, null, int 初始值(ok或canceled), initialData, initialExtras)
- 可以在依次降低的优先级Receiver中修改上面后三者的值, 来达到对最终接受者相应行为的控制
setResultCode(int)
, setResultData(String)
, setResultExtra(Bundle)
, setResult(int, String, Bundle)
- 可以在
onReceiver
中 调用中止方法abortBroadcast
, 后面优先级的都不会再接收. 但最终接受者会接收
sendOrderedBroadcast(i, PERM_PRIVATE, null, null,
Activity.RESULT_OK, null, null);
相关小记
- 优先级(-1000~1000, -1000及以下是系统保留值)
- 静态注册: 在Receiver中添加
android:exported="false
申明仅限内部使用 - 动态注册: 通过获取申请的权限
- 在fragment的
onCreate()
和onDestory()
方法中, 通过getActivity()
方法返回的值不同.
故可以使用getActivity().getApplicationContext()
方法, 其返回的值相同
或者在onStart()
和onStop()
方法中使用getActivity()
, 其返回的值相同.
- BroadcastReceiver的生命周期非常短暂, 比较适合短时的操作. 如:启动activity或service.
若想启动长时任务:
- 用Receiver启动, 交给service去做
- 通过goAsync().但不够灵活. 优点是可以设置有序广播的结果