Android编程权威指南学习之broadcast intent

这一章以两个方面完善PhotoGallery应用。首先,让应用轮询新结果并在有所发现时及时通知用户,即使用户重启设备后还没打开过应用。其次,保证用户在使用应用时不出现新结果通知。
1、一般Intent和broadcast intent
相同点:工作原理类似
区别:broadcast intent可同时被多个叫作broadcast receiver的组件接收。
结论:无论什么时候,activity和服务都应该响应隐式,但大多数场景,使用显示Intent就够了。broadcast intent之所以存在,最大的理由是它可以发送给多个接收者,broadcast receiver能响应显式intent,但不会这么用,因为显式intent只有一个接收者。
2、接收系统broadcast:重启后唤醒
目的:设备重启后,定时器依旧能继续运行。
背景:设备打开后,系统会发送一个BOOT_COMPLETED的广播,应用则通过创建并登记一个standalone broadcast receiver来对它进行监听。
2.1 standalone receiver
standalone receiver是一个在manifest配置文件中声明的broadcast receiver,即便应用进程已消亡,standalone receiver也可以被激活。
1)创建

    public class StartupReceiver extends BroadcastReceiver {
        private static final String TAG = "StartupReceiver";
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(TAG, "Received broadcast intent: " + intent.getAction());
        }
     }

2)登记

  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />//添加权限
  <receiver android:name=".StartupReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
 </receiver>

在配置文件中完成声明后,即使应用并未运行,只要有匹配的broadcast intent发来,broad receiver就会醒来接收。收到intent,broadcast receiver的onReceive( Context, Intent)方法即运行,随后会被销毁。

3)重启设备进行测试

2.2 receiver的使用
应用限制:onReceive(context, Intent)方法运行在主线程上,因此不能在该方法内做一些费时费力的任务,如网络连接或数据的永久存储等。
应用场景:便利型任务,启动activity或服务(不需要返回结果),以及系统重启后重置定时运行的定时器。
2.3 过滤前台通知消息
解决问题:通知消息虽然很有用。但应用开着的时候不应该收到通知消息。
解决方法:首先,我们发送(或接收)定制版broadcast intent(最后会锁定它,只允许PhotoGallery应用部件接收它)。其次,不再使用manifest文件,改用代码为broadcast intent动态登记receiver。最后,发送一个有序broadcast在一组receiver中传递数据,借此保证最后才运行某个receiver。
2.3.1 发送boadcast intent
定制版的broadcast intent:发送自己定制的broadcast intent。具体来讲,就是发送broadcast通知目标部件有新的搜索结果消息了。要发送broadcast intent,只需创建一个intent,并传入
sendBroadcast(Intent) 方法即可。这里,需要通过 sendBroadcast(Intent) 方法广播我们定
义的操作(action),因此还需要定义一个操作常量。

     public static final String ACTION_SHOW_NOTIFICATION =
"com.bignerdranch.android.photogallery.SHOW_NOTIFICATION";
     sendBroadcast(new Intent(ACTION_SHOW_NOTIFICATION));

2.3.2 动态broadcast receiver
可以编写一个类似于 StartupReceiver 的standalone broadcast receiver来接收intent,并在
manifest文件中登记;但这里行不通。我们需要在 PhotoGalleryFragment 存在的时候接收发过
来的intent。在配置文件中声明的standalone receiver会不断地接收intent,而且它还要设法知道PhotoGalleryFragment 的状态(这是个难点)。
使用动态broadcast receiver能解决问题。动态broadcast receiver是在代码中,而不是在配置文件中完成登记声明的。要在代码中登记,可调用 registerReceiver(BroadcastReceiver,
IntentFilter) 方法;取消登记时,则调用 unregisterReceiver(BroadcastReceiver) 方法。
receiver自身通常被定义为一个内部类实例,如同一个按钮点击监听器。然而,在 register-
Receiver(…) 和 unregisterReceiver(…) 方法中,我们要的是同一个实例,因此需要将
receiver赋值给一个实例变量。
新建一个VisibleFragment抽象类,后面PhotoGalleryFragment会继承它及它的广播接收器。

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);
            }
            @Override
            public void onStop() {
                    super.onStop();
                    getActivity().unregisterReceiver(mOnShowNotification);
            }
            private BroadcastReceiver mOnShowNotification = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                        Toast.makeText(getActivity(),"Got a broadcast:" + intent.getAction(),
Toast.LENGTH_LONG).show();
                }
            };
}
注意:在保留fragment中,设备旋转时onCreate()和onDestroy()方法中的getActivity()方法会返回不同的值,因此此时就得使用getActivity().getApplicationContext()方法。

2.3.3 私有权限的使用
背景:系统中的任何应用均可监听并触发我们的receiver,通常这种情况是不希望发生的。
方法一:在manifest配置文件里给receiver标签添加一个android:exported=”false”属性,声明它仅限应用内部使用。
方法二:在AndroidManifest.xml中添加permission标签来完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱技术爱生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值