注意:Android3.2版本之后,广播不能直接激活从来没有在手机上使用过的应用程序,所以如果要写一个打电话的广播接收者,必须要带一个Activity。
BroadcastReceiver
1.什么是BroadcastReceiverAndroid手机在一些事件发生的时候会发送广播, 例如: 开机成功, 收到短信, 拨打电话, SD卡状态改变, 电池状态改变
我们在程序中可以创建一个接收者, 接收这些广播, 处理对应的事件
2.定义广播接收者
定义类继承BroadcastReceiver, 重写onReceive()方法
在清单文件中声明<receiver>节点, 定义name属性, 定义<intent-filter>和<action>指定要接收的广播类型
<receiver>标签中可以指定一个permission属性, 要求发送者必须持有指定权限, 否则不接收.
3.广播的类型
无序广播:
所有接收者都可以收到, 不能中断, 不能使用结果数据.
sendBroadcast()
在发送时, 可以指定接收者权限, 也可以不指定权限. 如果指定了权限, 那么接收者必须持有这个权限才能收到广播.
有序广播:
多个接收者是逐个接收, 可以中断, 可以使用结果数据.
sendOrderedBroadcast()
在发送时和无序广播一样可以指定权限.
另外在发送有序广播时, 可以指定一些结果数据, 这些数据会被传递到接收者中. 每个接收者可以接收这些数据, 也可以修改这些数据
有序广播在接收者中可以调用abortBroadcast()中断, 中断之后, 后面的接收者就不能再收到广播
有序广播可以自定义一个接收者用来在广播序列的最后一个接收广播, 可以得到所有接收者修改之后的结果数据
注意: 无论有序广播还是无序广播, 都可以使用Intent对象传递数据. 和Activity中相同.
4.生命周期
广播接收者的生命周期非常短暂, 在收到广播时创建, onReceive()方法结束后就销毁
广播接收者onReceive()方法运行超过6秒就会ANR异常, 所以不要在主线程中做耗时的操作
如果在onReceive()方法中开新线程操作, 不会ANR, 但是由于生命周期结束, 很容易被杀死
一.无序广播和广播接收者:
【定义无序广播】
1.创建广播意图对象
2.发送无序广播
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void normal(View view){
Intent intent = new Intent("com.xxc.action.TEST");//创建广播的意图对象,指定广播的动作
//sendBroadcast(intent,"android.permission.INTERNET");//发送无序广播,第二个参数表示接收广播者必须拥有此权限,否则接收不到
sendBroadcast(intent,"com.xxc.permission.MYPERMISSION");//发送无序广播,第二个参数也可以是自定义权限
/*
* 在发广播应用的清单文件中配置自定义权限
* <permission android:name="com.xxc.permission.MYPERMISSION"></permission>
* 其他应用就可以使用此权限
*
* 同理:在接收方也可以定义发送方必须拥有某权限,接收方才接收
* <receiver android:name=".YourReceiver" android:permission="android.permission.INTERNET">
*/
}
}
清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxc.sender"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<!-- 在发送方自定义一个权限 -->
<permission android:name="com.xxc.permission.MYPERMISSION"></permission>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
定义广播接收者
1.继承BroadcastReceiver类
2.在清单文件中配置广播接收者
public class MyReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
System.out.println("MyReceiver收到广播");
}
}
广播接收者的清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxc.myreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="com.xxc.permission.MYPERMISSION"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<receiver android:name=".MyReceiver"><!-- 广播接收者类 android:permission=""可以指定拥有某权限的发送方,此接收方才接收 -->
<intent-filter><!-- 意图过滤器 -->
<action android:name="com.xxc.action.TEST"/><!-- 配置接收广播的哪种动作 和创建广播意图时指定的动作一样 -->
</intent-filter>
</receiver>
</application>
</manifest>
【定义有序广播】
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void ordered(View view){
//第二个参数表示接收广播者必须拥有此权限,否则接收不到 不需要则设置为null
//sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null);
/**
* 参数一:广播动作
* 参数二:权限
* 参数三:定义一个广播接收者,作为最后执行的接收者,无需在清单文件中注册 并且无论前面的广播接收者是否进行中断操作,此广播接收者都能接收到
* 第四个参数:指定一个handle,这个handle在哪个线程中创建,第三个参数定义的接收者的onReceive方法就在哪个线程中执行
*/
Bundle bundle = new Bundle();
bundle.putString("name", "张三");
bundle.putInt("age",10);
sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null, new FinalReceiver(), new Handler(), 100, "xxc", bundle);
}
}
广播接收者
public class MyReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
System.out.println("MyReceiver收到广播");
//获取结果数据
System.out.println("ResultCode "+getResultCode());
System.out.println("ResultData "+getResultData());
/*
* getResultExtras(true)
* true:如果sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null, null, null, 100, "xxc", bundle);
* 有序广播的最后个参数为null,getResultExtras(true)获取的并不是null,而是一个空的map
* false:如果sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null, null, null, 100, "xxc", bundle);
* 有序广播的最后个参数为null,getResultExtras(false)获取的就是null
*/
System.out.println("ResultExtras "+getResultExtras(true).getString("name")+", "+getResultExtras(true).getInt("age"));
/*
* 修改结果数据,在后面运行的广播接收者接收到的就是修改后的结果数据了
*/
Bundle bundle = new Bundle();
bundle.putString("name", "pkq");
bundle.putInt("age", 99);
setResultCode(000);
setResultData("ddd");
setResultExtras(bundle);
//setResult(000, "ddd", bundle); //这句话和上面3句一样
}
}