Android学习--broadcast intent

来源:互联网 发布:ppt软件官方下载 编辑:程序博客网 时间:2024/05/28 01:34
    上次提到利用broadcast Intent来解决打开应用后,我们依然会收到通知消息的问题。那么broadcast Intent到底是什么呢?

    broadcast intent的工作原理类似于intent,唯一不同的是broadcast intent可同时被多个组件接受。负责接受broadcast intent的是broadcast receiver。

一、利用broadcast intent解决设备重启问题

        设备重启后,那些持续运行的应用通常也需要重启。通过监听具有BOOT_COMPLETED操作的broadcast intent,可得知设备是否已完成启动。

        在配置文件中声明receiver,在配置文件中完成声明后,即使应用并未运行,只要有匹配的broadcast intent发来,broadcast receiver就会接收。一收到intent,broadcast receiver的onReceiver(Context,Intent)方法即开始运行,然后broadcast receiver就会销毁。broadcast receiver的存在很短暂,因此它的作用有效。例如,我们无法使用任何异步API或登记任何监听器,因为onReceive(Context,Intent)方法刚运行完,receiver就不存在了。onReceive(Context,Intent)方法同样运行在主线程上,因此不能在该方法内做一些耗时的重度任务,如网络连接或数据的永久存储等。

 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> //获得监听的权限 <receiver android:name=".StartupReveiver">    //在配置文件中声明receiver        <intent-filter>              <action android:name="android.intent.action.BOOT_COMPLETED" />  //监听BOOT_COMPLETED        </intent-filter> </receiver>

public class StartupReceiver extends BroadcastReceiver{      //覆盖broadcastReveiver的onReceive方法,                                                                                        //在接受到监听intent时重启定时器    @Override    public void onReceive(Context context, Intent intent){          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);         boolean isOn = prefs.getBoolean(PollService.PREF_IS_ALARM_ON, false);         PollService.setServiceAlarm(context, isOn);    }}

二、利用broadcast intent解决通知信息问题

(1)动态broadcast receiver
          动态broadcast receiver是在代码中,而不是在配置文件中完成登记声明的。要在代码中登记receiver,可调用registerReceiver(BroadcastReceiver,IntentFilter)方法;取消登记时,则调用unregisterReceiver(BroadcastReveiver)方法。

public abstract class VisibleFragment extends Fragment{     public static final String TAG = "VisibleFragment";        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();          }     };     @Override     public void onResume(){          super.onResume();          IntentFilter filter = new IntentFilter(PollService.ACTION_SHOW_NOTIFICATION);          getActivity().registerReveiver(mOnShowNotification, filter);       //在onResume()里登记receiver}     @Override     public void onPause(){          super.onPause();          getActivity().unregisterReceiver(mOnShowNotification);             //在onPause()里取消登记receiver     }}

(2)设置有权限的broadcast intent信息
          使用动态broadcast receiver存在一个问题,即系统中的任何应用均可监听并触发我们的receiver。我们可以通过增加权限来防止这种情况,如果receiver声明在manifest配置文件里,且仅限应用内部使用,则可在receiver标签中添加一个android:exported="false"属性。这样系统中的其他应用就再也无法接触到该receiver。另外还可以创建自己的使用权限,通常在AndroidManifest.xml中添加一个permission标签来完成。

<permission android:name="android.photogallery.PRIVATE" android:protectionLevel="signature" /><uses0permission android:name="android.photogallery.PRIVATE">

      发送带有权限的broadcast:
public class PollService extends IntentService{    public static final String PERM_PRIVATE = "android.photogallery.PRIVATE";    @Override    public void onHandleIntent(Intent intent){       sendBroadcast(new Intent(ACTION_SHOW_NOTIFICATION), PERM_PRIVATE);    }}

     设置broadcast receiver的使用权限:

@Override     public void onResume(){        super.onResume();        IntentFilter filter = new IntentFilter(PollService.ACTION_SHOW_NOTIFICATION);        getActivity().registerReveiver(mOnShowNotification, filter, PollService.PERM_PRIVATE, null);       //在onResume()里登记带有权限的receiver}


(3)使用ordered broadcast接受结果
          可以通过有序broadcast intent实现双向通信。有序broadcast允许多个broadcast receiver依序处理broadcast intent。另外,通过传入一个名为result receiver的特别broadcast receiver,有序broadcast还可实现让broadcast的发送者接受broadcast接受者发送的返回结果。以下代码只需发送YES或NO标志,因此使用int结果码即可。如需返回更多复杂数据,可使用setResultData(String)或setResultExtras(Bundle)方法。如需设置所有三个参数值,可调用setResult(int,String,Bundle)方法。
public abstract class VisibleFragment extends Fragment{      //在主程序中监听,收到广播来的相应Intent,更改返回的结果码     public static final String TAG = "VisibleFragment";        private BroadcastReceiver mOnShowNotification = new BroadcastReceiver() {          @Override          public void onReceive(Context context,Intent intent){               setResultCode(Activity.RESULT_CANCELED);    //设置返回的结果码          }     };}

     发送有序broadcast:

void showBackgroundNotification(int requestCode , Notification notification){  //在服务中调用,传入requestCode和notification对象       Intent i = new Intent(ACTION_SHOW_NOTIFICATION);       i.putExtra("REQUEST_CODE", requestCode);       i.putExtra("NOTIFICATION", notification);       sendOrderedBroadcast(i, PERM_PRIVATE, null, null Activity.RESULT_OK, null, null);               //五个参数分别是一个result receiver、一个支持result receiver运行的Handler、结果代码初始值、               //结果数据以及有序broadcast的结果附加内容。}

     实现result receiver,一直在后台监听,判断ResultCode()的值,如OK则发送通知信息,如CANCELED则不发送通知信息并返回:

public class NotificationReceiver extends BroadcastReceiver{    private static final String TAG = "NotificationReceiver";    @Override    public void onReceive(Context c, Intent i){        Log.i(TAG, "received result: " + getResultCode());        if(getResultCode() != Activity.RESULT_OK)            return;        int requestCode =  i.getIntExtra("REQUEST_CODE", 0);        Notification notification = (Notification)i.getParcelableExtra("NOTIFICAION");        NotificationManager notificationManager = (NotificationManager)                        c.getSystemService(Context.NOTIFICATION_SERVICE);        notificationManager.notify(requestCode, notification);   } }

    在AndroidManifest.xml中登记notification receiver,并把优先级设为最低:

<receiver android:name=".NotificationReceiver"  android:exported="flase">  //设置权限,仅限应用内部  <intent-filter     android:priority="-999">   //设置优先级为最低(保证其运行在最后)     <action         android:name="android.photogallery.SHOW_NOTIFICATION" />  </intent-filter></receiver>


0 0