BroadcastReceiver 广播接收者

                      BroadcastReceiver 广播接收者

1、介绍

       系统中消息的一种变种;就是当一个事件发生时,比如,系统突然断网,系统就发一个广播消息给所有的接收者,所有的接收者在得到这个消息之后,就知道,啊哦,现在没网络了,我的程序应该怎么办!系统的一些事件,比如来电,来短信,等等,都会发广播;可监听这些广播,并进行一些处理;

       Android3.2以后,为了安全起见,对于刚安装的应用,需要通过点击进入应用(界面,用户确认之后),接收者才能起作用;以后即使没有启动其界面,也能接收到广播;

2、定义广播接收者

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

     2)清单文件中声明<receiver>,需要在其中配置<intent-filter>指定接收广播的类型;

     3)当接收到匹配广播之后就会执行onReceive方法;

     4)有序广播中,如果要控制多个接收者之间的顺序,可在<intent-filter>配置priority属性,系统默认为0,值越大,优先级越高;

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

<span style="font-family:FangSong_GB2312;font-size:18px;"><!-- 配置广播接收者,监听播出电话 -->
     <receiver android:name="com.itheima.ipdialer.CallReceiver" >
          <intent-filter>
               <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
           </intent-filter>
 </receiver></span>

3、广播的分类

    1)普通广播:普通广播不可中断,不能互相传递数据;

    2)有序广播:广播可中断,通过调用abortBroadcast()方法;接收者之间可以传递数据

4、广播接收者的注册方式

    4大组件中,只有广播接收者是一个非常特殊的组件,其他3大组件都需要在清单文件中注册;广播接收者,有2中注册方式:清单文件与代码方式,区别:

   1)清单文件注册广播接收者,只要应用程序被部署到手机上,就立刻生效,不管进程是否处于运行状态;

   2)代码方式,如果代码运行了,广播接收者才生效,如果代码运行结束,广播接收者,就失效;这属于动态注册广播,临时用一下,用的时候,register,不用时unregister;

代码方式示例:

// 广播接收者
	private class InnerReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String phone = getResultData();
			String address = AddressDao.queryAddress(getApplicationContext(), phone);
			showAddress(address);
		}
	}
	// 注册示例代码
	public void onCreate() {
		// == 服务启动时,注册广播接收者 ==
		innerReceiver = new InnerReceiver();
		// 指定意图过滤器
		IntentFilter filter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
		this.registerReceiver(innerReceiver, filter);
	}
	// 销毁	
	public void onDestroy() {
		// == 服务停止时,移除广播接收者 ==
		this.unregisterReceiver(innerReceiver);
		innerReceiver = null;
		super.onDestroy();
	}

5、发送广播

  1)发送普通广播

    ①、使用sendBroadcast()方法可发送普通广播;

    ②、通过Intent确定广播类型,可携带数据,所有接收者都可以接收到数据,数据不能被修改,不会中断;

  接收者无序(试验测试,是按照安装顺序来接收的);

    ③、广播时,可设置接收者权限,仅当接收者含有权限才能接收;

    ④、接收者的<receiver>也可设置发送方权限,只接受含有相应权限应用的广播;

发送者:

        Intent intent = new Intent("com.itheima.broadcast.TEST");	// 指定动作;接收者,需要配置 intent filter才能接受到此广播
	intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);	// 包含未启动的过的应用(也可以收到广播),默认为不包含
	intent.putExtra("data", "这是来着广播发送者发来的贺电");		// 广播发送者intent中的数据,接收者,修改不了
	sendBroadcast(intent, null);								// 发送无序广播,异步获取数据,不可中断,接收者之间不可传数据

接收者:

       public class AReceiver extends BroadcastReceiver {
		public void onReceive(Context context, Intent intent) {
			System.out.println("AReceiver: " + intent.getStringExtra("data"));
		}
	}
      <receiver android:name="com.itheima.a.AReceiver">
            <intent-filter android:priority="2" >
                <action android:name="com.itheima.broadcast.TEST" />	<!—接收指定动作的广播 -->
            </intent-filter>
      </receiver>

注意:

       如果要在广播接收者中打开Activity,需要设置一下Intent.FLAG_ACTIVITY_NEW_TASK因为广播接收者是没 有Activity任务栈的,所以需要加上这个标记,方能在广播接收者中打开Activity,如:

        public void onReceive(Context context, Intent intent) {
		Log.i(TAG, "打电话了。。。");
		String phone = this.getResultData();
		if ("2008".equals(phone)) {
			// == 打开手机防盗功能界面 ==
			Intent safeIntent = new Intent(context, LostFindActivity.class);
			safeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);			// 使Activity也能在Receiver中启动
			context.startActivity(safeIntent);
			abortBroadcast();					// 中断广播
			setResultData(null);				// 把电话号码设为null,就没有了通话记录
		}
	}

2)发送有序广播

     a.   sendOrderedBroadcast()发送有序广播;

     b.   通过Intent确定广播类型, 携带数据,Intent的数据同样修改无效;

     c.   跟普通广播一样,也可以设置相应的权限;

     d.   接收者可在<intent-filter>定义android:priority定义优先级,数字越大,优先级越高;

     e.   有序广播会被接收者逐个接收,中途可以中断,或添加、修改数据;

     f.   可以指定一个自己的广播接收者, 这个接收者将最后一个收到广播、不会被中断、不需要任何权限、不需要配置;

     g.   可以指定一个Handler用来在自己的接收者中进行线程通信;

 

发送者:
        Intent intent = new Intent("com.itheima.broadcast.TEST");	// 指定动作;接收者,需要配置 intent filter才能接受到此广播
	intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);	// 包含未启动的过的应用(也可以收到广播),默认为不包含
	intent.putExtra("data", "这是来着广播发送者发来的贺电");		// 广播发送者的intent中的数据,接收者,修改不了
	// == 有序广播时,传递的数据可修改 ==
	Bundle bundle = new Bundle();
	bundle.putString("name", "关羽");
	bundle.putInt("age", 22);
	/* 定义权限,要求接收者,要有 com.itheima.permission.broadcast.RECEIVE 才能接收;
	 * 配置了最后接收者,Creceiver,无论你们怎么弄,我都可以收到广播,而且我不要配置,不要权限
	*  handle为null,表示使用系统默认的
	*  传递了数据 1, “MainActivity”, bundle 这些都是可以在接收者修改的
	*/
	this.sendOrderedBroadcast(intent, "com.itheima.permission.broadcast.RECEIVE", new CReceiver(), null, 1, "MainActivity", bundle);

    <!-- 定义一个权限 -->
    <permission android:name="com.itheima.permission.broadcast.RECEIVE" >
    </permission>
    <!- 使用该权限-->
    <uses-permission android:name="com.itheima.permission.broadcast.RECEIVE" />

接收者AReceive:

       public void onReceive(Context context, Intent intent) {
		System.out.println("AReceiver: " + intent.getStringExtra("data"));
		Bundle bundle = this.getResultExtras(true);		// 设置为true,表示即使没有传递Bundle数据,不会出现空指针
		String message = String.format("%s : %s : %s, %s", getResultCode(), getResultData(), bundle.getString("name"), bundle.getInt("age"));
		System.out.println(message);					// 如果优先级高于其他接收者,将打印发送者的数据

		// == 修改有序发送者,发来的数据 ==
		bundle.putString("name", "赵子龙");
		bundle.putInt("age", 222);
		this.setResult(2, "AReceiver", bundle);

		// == 修改Intent中的数据,无效 ==
		intent.putExtra("data", "AReceiver 修改了数据");

		this.setResultData("这是来自AReceiver的信息");
		// this.abortBroadcast(); 						// 中断,比它优先级低的接收者,将不能接收到广播了
	}
	<!-- 要求广播发送者必须有对应的权限,我才收 -->
      <receiver  android:name="com.itheima.a.AReceiver"
            android:permission="com.itheima.permission.broadcast.RECEIVE" >	
            <intent-filter android:priority="2" >
                <action android:name="com.itheima.broadcast.TEST" />
            </intent-filter>
        </receiver>

   接收者BReceive:代码及配置与上类似,只是优先级比A的低

 

6、广播的生命周期

    a.  广播接收者的生命周期非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁;

    b.  广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框;

    c.  最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉;

    d.  耗时的较长的工作最好放在服务中完成;



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值