android之旅15 广播与广播接收者: 接收系统广播

来源:互联网 发布:狗狗币 知乎 编辑:程序博客网 时间:2024/05/29 21:18
  • 广播的意义其实就是告诉多个APP同一事件,是普通一对一事件的扩展
  • 电量改变、收发短信、开机、电话、屏幕解锁等,都是广播
  • 广播接收者是四大组件之一。注意不是广播
  • 四大组件的都要在清单文件manifest文件中定义,注意和Activity同级
  • 注意权限的问题,接收打电话、短信侵犯了隐私
  • 广播实际上是先发一条广播,广播接收者先收到广播,可以修改广播数据,最后发给实际生效的Activity
  • 广播存活的进程就是部署所在的application,即使该进程被杀死了,当广播发出时,系统会启动这个进程,然后发广播给该进程。 这种监测者的实现方式是为了给系统节省资源,没必要一直开着这种监测进程
  • 如果广播接收者进程是用户手动关闭(app info下的FORCE STOP,见下图),那就不会再次启动,4.0之后的特性
  • 广播实际上也是通过Intent发送的
  • 广播接收者进程如果从来没有启动过,4.0以后就不会生效
    这里写图片描述

电话短信接收者

<application>    <activity>    </activity>    <receiver android:name="packageName.ClassName">        <intent-filter>        <action ---- 指定接收什么类型的广播,这里值是表示往外打电话的广播        android:name="android.intent.action.NEW_OUTGOING_CALL"/>           </intent-filter>    </receiver>    <receiver android:name="packageName.ClassName">        <intent-filter android:priority="1000"> -- 定义优先级,优先级[-1000,1000]        <action ---- 接收收短信的广播,这个不提示,操蛋        android:name="android.provider.Telephony.SMS_RECEIVED"/>           </intent-filter>    </receiver></application>
// 电话接收者public class CallReceiver extends BroadcastReceiver{    public void onReceive(Context c, Intent intent){        // 会带过来拨打的电话号码        String number = getResultData();        //广播接收者不是Context子类,因此把Context传进来        String str1 = context.getSharedPreferences("ip", Context.MODE_PRIVATE).getString("str1");        number = str1+number;        setResultData(number); //将数据设置给广播    }   }
// 短信接收者public class SmsReceiver extends BroadcastReceiver{    public void onReceiver(Context context Intent intent){        Bundle bundle = intent.getExtras();         //短信的抽象叫做pdus, pdu是协议数据单元,每个object表示一条短信        Object[] objects = bundle.get("pdus");        for(Object o : objects){//多条短信原因:内容超过运营商规定长度            SmsMessage sms = SmsMessage.createFromPdu((byte[])o);            //sms就是短信的所有东西。。包括地址,短信内容等            if (sms.getOriginatingAddress().equals("39393")){            //短信应用和短信是两回事,收到短信这个事件会发广播,            //短信应用收到广播然后显示出来                abortBroadcast(); //丢弃广播,低优先级接收者就收不到了            }        }    }}

SD卡状态广播接收

  • 广播也是通过Intent传递的,SD卡广播定义的时候就有data,因此需要完全匹配,因此定义了一个data
<!--同一个Receiver接收多个广播的写法--><intent-filter>   <action android:name="android.intent.action.MEDIA_MOUNTED"/>   <action android:name="android.intent.action.MEDIA_REMOVED"/>   <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>   <data android:scheme="file"/></intent-filter>
public class SDCardCast extends BroadcastReceiver{    public void onReceive(Context context, Intent){        String str = intent.getAction();        if ("android.intent.action.MEDIA_MOUNTED".equals(str)){        }else if(){            //业务逻辑.......        }    }}

开机广播接收者

// BOOT_COMPLETED是广播Action的名字public class BootReceiver extends BroadcastReceiver{    public void onReceive(Context context, Intent intent){        Intent it = new Intent(context, XXX.class);        //在context外部启动Activity必须设置这个flag,实际就是创建一个新的Activity栈        it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        context.startActivity(it);    }}

应用状态广播

  • 应用状态有三种:安装、更新、卸载
// PACKAGE_ADDED\PAGEAGE_REMOVED\PACKAGE_REPLACED//intent-fliter还要定义一个data android:scheme="package"public class AppStatusReceiver extends BroadcastReceiver{    public void onReceive(Context c, Intent it){        String action = it.getAction();        Uri uri = it.getData();        if (action.equals("PACKAGE_ADDED")){            System.out.println(uri.toString());        }else if(){            /*                其他逻辑.....            */        }    }}
  • 总结下:
  • 定义类继承BroadcastReceiver
  • manifest中定义Receiver,并通过intent-filter中的action定义接收广播类型
  • 权限添加
0 0