1.监听系统发送的一个广播
这里我们监听一下用户打电话时系统发出的广播
/**
* 1.创建接收广播的监听类
*/
public class PhoneReceiver extends BroadcastReceiver {
//4.收到广播时会调用此方法
@Override
public void onReceive(Context context, Intent intent) {
Log.v("myApp","PhoneReceiver onReceive");
}
}
在Manifest.xml文件中注册监听哪一个广播
<!-- 2.注册监听 -->
<receiver android:name="com.mazhan.receiver.PhoneReceiver">
<!-- 3.过滤是监听哪一个广播 4大组件除了Activity的action标签需要category属性外 其他的不需要-->
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
2.监听收到短信的广播
流程也是一样的,在Manifest文件中进行广播注册
<receiver android:name=".receiver.SmsReceiver">
<!-- priority优先级 int类型的数据 范围-1000~1000 如果是1000 优先级是最高的-->
<intent-filter android:priority="1000">
<!-- 关心的事件:接收短信 -->
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<!-- 短信接收是一个敏感的操作 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
在SmsReceiver 中,在收到短信的时候,进行方法回调处理
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取跟短信相关的数据
Bundle bundle = intent.getExtras();
//短信在发送的过程中 可能会变成多条 所以这里把它封装成一个数组
Object[] objs = (Object[]) bundle.get("pdus");
for (Object obj : objs) {
//短信在手机里面是以2进制的字节码进行传输
byte[] buff=(byte[]) obj;
//将二进制转换成一条短信
SmsMessage message=SmsMessage.createFromPdu(buff);
//1.获取发信人
String phone = message.getDisplayOriginatingAddress();
//2.短信的内容
String smsContent = message.getDisplayMessageBody();
Log.v("520it", phone+" "+smsContent);
//发条信息返回去...
}
//2.告诉广播 不要继续发下去了 终止广播
abortBroadcast();
}
}
3.监听应用安装和卸载的广播
<receiver android:name=".apkreceiver.ApkStatusReceiver">
<intent-filter>
<!-- 应用安装/卸载事件比较关系 -->
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<!-- 应用安装卸载 应用开发包.apk -->
<data android:scheme="package" />
</intent-filter>
</receiver>
public class ApkStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_PACKAGE_ADDED)) {
Log.v("app", "应用被安装");
}else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
Log.v("app", "应用被卸载");
}
}
}
4.自定义广播
自定义的广播也是可以跨进程进行通讯的,方式和activity的隐式启动类似
下面的自定义广播,发送端和接收端是两个app程序,当然是在同一个app中也是可以的
广播发送端
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("broadcast_price", 10);
intent.setAction("com.mazhan.broadcast01");
sendBroadcast(intent);
}
});
}
}
广播接收端,和接受系统的广播是一样的流程
注册广播接收器
<receiver
android:name=".customReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.mazhan.broadcast01"/>
</intent-filter>
</receiver>
监听收到广播时的方法回调
public class customReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
int price = intent.getIntExtra("broadcast_price", 0);
Log.v("myApp", "接收到了自定义的广播 broadcast_price=" + price);
}
}
这样的广播属于无序广播,无序广播并不是说,广播执行没有先后顺序,而是说,后一个广播是否能够执行,不受上一个接收者的影响。
比如说
sender发送无序广播给A,B,C三个接收者,那么接收到广播的顺序,就和A,B,C在Manifest中的优先级一样。即使其中B abortBroadcast(),丢弃了广播,但是也不会影响C接收广播。
有序广播
sender发送有序广播给A,B,C三个接收者,如果B abortBroadcast(),丢弃了广播,那么C就接收不到广播了。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("broadcast_price", 10);
intent.setAction("com.mazhan.broadcast01");
// sendOrderedBroadcast(@RequiresPermission
// @NonNull Intent intent,
// @Nullable String receiverPermission, 设置查看广播的权限
// @Nullable BroadcastReceiver resultReceiver,结果广播接收者 不需要再配置中注册
// @Nullable Handler scheduler,一般没用
// int initialCode, 初始化编码 区别你的广播
// @Nullable String initialData,广播名
// @Nullable Bundle initialExtras,传递各种数据
// );
sendOrderedBroadcast(intent,
null,
new ResultReceiver(),
null,
0,
null,
null);
}
});
}
}
public class AReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
int price = intent.getIntExtra("broadcast_price", 0);
Log.v("myApp", "AReceiver broadcast_price=" + price);
}
}
public class BReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
int price = intent.getIntExtra("broadcast_price", 0);
Log.v("myApp", "BReceiver broadcast_price=" + price);
Bundle bundle = new Bundle();
bundle.putInt("price", 100);
setResultExtras(bundle);
abortBroadcast();
}
}
这种情况下,B丢弃了广播,C就无法接收到广播了。但是在发送广播的时候,设置了ResultReceiver这个类,也就是说,广播最终的结果还是会被接收到
public class ResultReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Bundle bundle = getResultExtras(true);
int price = bundle.getInt("price");
Log.v("myApp", "ResultReceiver price=" + price);
}
}
5.在广播接收者里面不可以执行耗时操作
下面这种情况下,当CustomReceiver 接收到广播的时候,主线程就会被卡住
public class CustomReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.v("myApp", "CustomReceiver onReceive");
SystemClock.sleep(1000*10);
}
}