广播接收者(BroadcastReceiver)

广播接收者(BroadcastReceiver)

1.定义广播接受者

静态注册广播

  • 定义类继承BroadcastReceiver,重写onReceive方法

    public class BroadCastReceiverDemo extends BroadcastReceiver {
    
      @Override
      public void onReceive(Context context, Intent intent) {
    
          Toast.makeText(context,"广播接受者--Boot Complete.",Toast.LENGTH_LONG).show();
      }
    
    }
    
  • 清单文件中声明<receiver>,需要在其中配置<intent-filter>指定接收广播的动作

    <!-- 开机广播接受者 -->
    <receiver android:name=".BroadCastReceiverDemo">
         <intent-filter>
              <!-- 注册开机广播地址-->
              <action android:name="android.intent.action.BOOT_COMPLETED"/>
              <category android:name="android.intent.category.DEFAULT" />
          </intent-filter>
     </receiver>
    
  • 当接收到匹配广播之后就会执行onReceive方法

     @Override
      public void onReceive(Context context, Intent intent) {
    
          Toast.makeText(context,"广播接受者----Boot Complete.",Toast.LENGTH_LONG).show();
      }
    
  • BroadcastReceiver的优先级

     <!-- 开机广播接受者 -->
    <receiver android:name=".BroadCastReceiverDemo">
         <intent-filter android:priority="2147483647">
              <!-- 注册开机广播地址-->
              <action android:name="android.intent.action.BOOT_COMPLETED"/>
              <category android:name="android.intent.category.DEFAULT" />
          </intent-filter>
     </receiver>
    

    2147483647是最高优先级,默认是0.

动态注册广播

  • BroadcastReceiver除了在清单文件中声明,也可以在代码中声明,使用registerReceiver方法注册Receiver

    public class MainActivity extends Activity {
    
       private CodeReceiver receiver;
       private IntentFilter filter;
    
       @Override
       protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
           
            filter = new IntentFilter("android.intent.action.SCREEN_ON");
            filter.setPriority(100);             //优先级
            receiver = new CodeReceiver();
           
            registerReceiver(receiver, filter);  // Activity创建时注册接收者
       }
      
       @Override
       protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(receiver);       // Activity退出时注销接收者
       }
    
    }
    

2.发送广播

无序广播

  • 使用sendBroadcast方法发送
  • 被所有广播接收者接收,无序,不可中断
  • 广播时可设置接收者权限,仅当接收者含有权限才能接收
  • 接收者的<receiver>也可设置发送方权限,只接收含有权限应用的广播

无序广播发送方法

void sendBroadcast (Intent intent, String receiverPermission)

参数:

intent The Intent to broadcast; 传给接收者的意图 all receivers matching this Intent will receive the broadcast.所有匹配的广播接受者都回收到这一意图

receiverPermission (optional)可选的 String naming a permission that a receiver must hold in order to receive your broadcast.一个接收者必须拥有的权限 If null, no permission is required. 如果为null,则没有要求

示例:

sendBroadcast(intent, null);

有序广播

  • 使用sendOrderedBroadcast方法发送
  • 接收者可以在<intent-filter>中定义android:priority定义优先级,数字越大优先级越高
  • 被各个广播接收者逐个接收,中途可以中断或者添加数据
abortBroadcast()  
getResultExtras(true).putString("data", "新增数据");
<receiver android:name="com.top.myreceiver.MyReceiver1" >
     <intent-filter android:priority="1000">
         <action android:name="com.top.mybroadcast.xxx" />
     </intent-filter>
</receiver>

<receiver android:name="com.top.myreceiver.MyReceiver2" >
    <intent-filter android:priority="500">
      <action android:name="com.top.mybroadcast.xxx"/>
    </intent-filter>
</receiver>
        
<receiver android:name="com.top.myreceiver.MyReceiver3" >
    <intent-filter android:priority="100">
         <action android:name="com.top.mybroadcast.xxx" />
    </intent-filter>
</receiver>

  • 有序广播发送方法
void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)

参数
intent* The Intent to broadcast; 传给接收者的意图 all receivers matching this Intent will receive the broadcast.所有匹配的广播接受者都回收到这一意图

receiverPermission (optional)可选的 String naming a permission that a receiver must hold in order to receive your broadcast.一个接收者必须拥有的权限 If null, no permission is required. 如果为null,则没有要求

resultReceiver Your own BroadcastReceiver to treat as the final receiver of the broadcast. 指定一的广播的最终接受者(必须执行的)
scheduler A custom Handler with which to schedule the resultReceiver callback;指定你的接收者回掉的handler; if null it will be scheduled in the Context's main thread. 如果为空,则默认为主线程
initialCode An initial value for the result code.初始的结果码 Often Activity.RESULT_OK. 通常设置

initialData An initial value for the result data.初始的结果数据 Often null. 通常为null

initialExtras An initial value for the result extras.初始化附加信息bundle; Often null通常为null

示例

Intent intent = new Intent("com.top.broadcast.TEST");         // 创建意图对象, 设置广播的动作
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); // 广播是否启动那些没有启动过的应用
intent.putExtra("data", "最初的数据!!!");                                  // 这里的数据不会被修改
Bundle bundle = new Bundle();
bundle.putString("name", "张三");
sendOrderedBroadcast(intent, "com.top.permission.BROADCAST", new ResultReciever(), null, 1, "MainActivity", bundle);

短信黑名单

  • Android系统在收到短信的时候会发送一条有序广播,我们如果定义一个接收者接收这个广播,就可以得到短信内容,也可以拦截短信
  • 定义广播接收者接收广播android.provider.Telephony.SMS_RECEIVED
  • 在onReceive方法内部调用Intent的getExtras()再调用get()获取其中pdus字段,得到一个Object[],其中每一个元素都是一个byte[]
  • 通过SmsMessage类的createFromPdu方法创建SmsMessage对象
  • 从SmsMessage对象中即可获取发送者号码、短信内容、发送时间等信息
  • 需要接收短信权限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>
  • Android系统中收到短信的通知是一个有序通知,我们如需拦截垃圾短信,可以配置较高的priority,收到信息进行判断是否abortBroadcast()

自动IP拨号

  • 定义广播接收者接收 android.intent.action.NEW_OUTGOING_CALL
  • 需要权限 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
  • 在onReceive方法中使用getResultData() 和 setResultData() 方法获取和设置电话号码

广播接收者生命周期 Broadcast receiver lifecycle

  • 广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁。当广播消息抵达接收器时,Android调用它的onReceive()方法并将包含消息的Intent对象传递给它。广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态。
    拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死。但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。
    //广播接收器只有一个回调方法:void onReceive(Context curContext, Intent broadcastMsg)
  • 广播接收者是在主线程中执线的,广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框
  • 最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
  • 耗时的较长的工作最好放在服务中完成

在android系统里面有很多内置的广播事件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容