android广播接收者

生命周期:


 

 

生命周期只有十秒左右,如果在onReceive()内做超过十秒内的事情,就会报错。

 

每次广播到来时,会重新创建BroadcastReceiver对象,并且调用onReceive()方法,执行完以后,该对象即被销毁.当onReceive()方法在10秒内没有执行完毕,Android会认为该程序无响应.所以在

BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR

广播的分类:

A.无序广播:所有与广播中的action匹配的广播接收者都可以接收到这条广播,但是并没有先后的顺序,视为同时收到(发送一个广播,所以监听该广播的广播接收者都可以监听到改广播。)


B.有序广播:所有与广播中的action匹配的广播接收者都可以收到这条广播,但是是先后顺序,按照广播接收者的优先级排序

sendOrderedBroadcast(intent,receiverPermission);

sendOrderedBroadcast(intent,receiverPermission, resultReceiver,

       scheduler, initialCode, initialData, initialExtras)

意图,广播,所有匹配的这一意图将接收机接收广播。

receiverPermission这是权限,一个接收器必须持以接收您的广播。如果为null,不经许可的要求。
resultReceiver您自己BroadcastReceiver来当作最后的广播接收器。
调度自定义处理程序,用以安排resultReceiver回调;如果为null将语境中的主线程举行。
initialCode一种结果代码的初始值。通常为Activity.RESULT_OK。这个值是-1;为其他int型 也可以,如0,1,2;
initialData一种结果数据的初始值。通常情况下为空,是String类型;
initialExtras一种结果额外的初始值。通常情况下为空,是Bundle;

拓展:

1,  该广播的级别有级别之分,级别数值是在-1000到1000之间,值越大,优先级越高;

2,  同级别接收是先后是随机的,再到级别低的收到广播;

3,  同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。(abortBroadcast())

4,能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该钟广播是否截断掉。

5,实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。

C.异步广播, 当处理完之后的Intent,依然存在,这时候registerReceiver(BroadcastReceiver,IntentFilter)还能收到他的值,直到你把它去掉,不能将处理结果传给下一个接收者,无法终止广播.

sendStickyBroadcast(intent);

当处理完之后的Intent,依然存在,直到你把它去掉。

发这个广播需要权限<uses-permission android:name="android.permission.BROADCAST_STICKY"/>

去掉是用这个方法removeStickyBroadcast(intent);但别忘了在执行这个方法的应用里面AndroidManifest.xml同样要加上面的权限;

sendStickyOrderedBroadcast(intent,resultReceiver, scheduler,

       initialCode, initialData,initialExtras)

这个方法具有有序广播的特性也有异步广播的特性
发送这个广播要:<uses-permissionandroid:name="android.permission.BROADCAST_STICKY" />这个权限。才能使用这个方法。如果您并不拥有该权限,将抛出SecurityException的。

代码中注册广播:

(三)
代码中注册广播

注册广播方法一:registerReceiver(BroadcastReceiverreceiver, IntentFilter filter),第一个参数是我们要处理广播的BroadcastReceiver(广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器。

注册广播方法二:registerReceiver(receiver, filter, broadcastPermission, scheduler),第一个参数是BroadcastReceiver(广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器;第三个参数是广播权限;第四个参数是Hander;

注意:权限重复现象,如果功能清单文件里注册了权限,在该方法再注册,则receiver无法收到广播,如果功能清单文件里没有注册了权限,该方法注册也无法收到。当该方法没有注册权限,功能清单里注册的时候,receiver能收到广播。

 总结:在Activity中代码注册广播建议在:onResume()中注册

代码中注销广播

/unregisterReceiver(mBatteryInfoReceiver);

在Activity中代码注销广播建议在:onPuase() 中注销;

不要这这里面注销Activity.onSaveInstanceState(),因为这个方法是保存Intent状态的。


广播的注意事项:

1.凡是广播必须是要到AndroidMainfest中配置信息的

<receiver android:name=".CallReceive">   -->类的全路径
            <intent-filter >
                <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>   -->设置的是接收什么样的广播,根据实现的功能而定
            </intent-filter>
 </receiver>


实例:

ip拨号器(实现拨打电话的前面加上特定的ip)

<span style="font-size:12px;">/**
 * 1.定义java类,继承BoardcastReceiver
 * 2.在清单文件中配置reveiver节点(指定name,全类名)
 * 3.在intent-filter的节点中,指定action子节点,action的值必须要和接收广播的action的值匹配
 * @author abc
 *
 */
public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	/**
	 * 思路:1.将EditText的字符提取出来
	 * 2.创建一个SharedPreferences的存储对象
	 * 3.将字符串存储进去(存储的顺序是先获得edit(),然后putstring)
	 * 4.编辑,提交
	 * @param v
	 */
	public void click(View v){
		EditText dt = (EditText) findViewById(R.id.ed);
		SharedPreferences sp=getSharedPreferences("ip",	MODE_PRIVATE);
		Editor ed=sp.edit();
		ed.putString("ipNumbe",dt.getText().toString());//键值对的形式,前面是键后面是值
	}
}

public class CallReceive extends BroadcastReceiver{

	/**
	 * 思路:
	 * 1.获得原来的打电话的号码
	 * 2.通过上下文的getSharedPreference获得之前保存的数据,即文本框传进来的数据)
	 * 3.将看原来的电话加上我们想给他预订的ip
	 * 4.将电话重新返回给广播
	 */
	
	@Override
	public void onReceive(Context context, Intent intent) {
			System.out.println("call...");
			String phone=getResultData();
			SharedPreferences sp=context.getSharedPreferences("ip",context.MODE_PRIVATE );
			String ipNumber=sp.getString("ipNumber", "");
			phone=phone+ipNumber;
			setResultData("phone");
			abortBroadcast();
	}
}

同样要在AndroidMainfest配置信息(在系统默认的</activity>之后)
</span><span style="font-size:12px;">       <receiver android:name=".CallReceive">
            <intent-filter >
                <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
            </intent-filter>
        </receiver> 
</span>


短信防火墙(实现短信的拦截)

<span style="font-size:12px;">public class SmsReceiver extends BroadcastReceiver {

	/**
	 * 思路: 
	 * 1.拿到短信,封装在intent里面 
	 * 2.把intent放在Bundle里面
	 * 2.以pdus为键,取出短信的内容,保存到Object[]里 
	 * 3.把object转成byte数组
	 * 注:联想系统存储短信的思路:
	 * 1.把短信转成字节数组 
	 * 2.把字节数组存到Object[]数组里面
	 *3.以"pdus"为key,把object[]数组储存到Bundle里面,在把Bundle 存储到Intent里面
	 *
	 *小结:
	 *1.AndroidMainfest需要配置的信息receiver android:name=".SmsReceiver">
			<intent-filter android:priority="1000" >
					<action android:name="android.provider.Telephony.SMS_RECEIVED"/>			    
			</intent-filter>            
        </receiver>
       
	 * 2.加权限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
			
		
			Bundle bundle = intent.getExtras();
			Object[] obj = (Object[]) bundle.get("pdus");
			for (Object object : obj)
				{
					SmsMessage sms=SmsMessage.createFromPdu((byte[]) object);
					if(sms.getOriginatingAddress().equals("1111")){
						abortBroadcast();
					}
					System.out.println(sms.getMessageBody());
				}
	}

}
其他的程序:一个系统创建的MainActivity,AndroidMainfest中的配置
</span>

监听sd卡的状态(可正常使用,被卸载,,不能使用)

<span style="font-size:12px;">/**
 * 小结:
 * 1.虚拟机4.0以上的没有sd
 * 2.AndrodMainfest中配置
 * <receiver android:name=".SDStatusReceiver" >
            <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>
        </receiver>
        其他一眼明了
 * @author abc
 *
 */
public class SDStatusReceiver extends BroadcastReceiver {

			@Override
			public void onReceive(Context context, Intent intent) {
				String action=intent.getAction();
				if("android.intent.action.MEDIA_MOUNTED".equals(action)){
					Toast.makeText(context, "SD可用", 0).show();
				}
				if("android.intent.action.MEDIA_REMOVED".equals(action)){
					Toast.makeText(context, "SD被卸载", 0).show();
				}
				if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
					Toast.makeText(context, "SD不可用", 0).show();
				}
			}

}
</span>

监控应用的状态(安装,卸载,更新)

<span style="font-size:12px;">public class AppStatusReceiver extends BroadcastReceiver {

	/**
	 * 在AndroidMainfest中添加:
	 * <receiver android:name=".AppStatusReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />

                <data android:scheme="package" />
            </intent-filter>
        </receiver>
        其他的一眼明了
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		String action=intent.getAction();
		Uri uri=intent.getData();
		if("android.intent.action.PACKAGE_ADDED".equals(action)){
			Toast.makeText(context, uri.toString()+"被安装了", 0).show();
		}
		if("android.intent.action.PACKAGE_REPLACED".equals(action)){
			Toast.makeText(context, uri.toString()+"被更新了", 0).show();
		}
		if("android.intent.action.PACKAGE_REMOVED".equals(action)){
			Toast.makeText(context, uri.toString()+"被卸载了", 0).show();
		}
		
	}

}</span>

自定义广播的方法(用的少)

<span style="font-size:12px;">public class MainActivity extends Activity {

	/**
	 * 自定义广播:
	 * 在发送的广播里面设置intent.setAction("aweiyo");//字符串是自己定义的
	 * 在接受的广播里里面将AndroidMainfest添加:
	 * <receiver android:name=".ReceiveBroad">
            <intent-filter >
                <action android:name="aweiyo"/>//这个就是之前自己设定的
            </intent-filter>
        </receiver>
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void click(View v){
		Intent intent=new Intent();
		intent.setAction("aweiyo");
		sendBroadcast(intent);
	}

}
注:另外一个接收广播的只要在配置文件中添加如上的节点文件,然后新建的类继承BroadcastReceiver即可
</span>

注:原文部分引自(http://yangguangfu.iteye.com/blog/1063732)

(完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值