参考:https://www.cnblogs.com/wanghaoyuhappy/p/5292733.html
https://blog.youkuaiyun.com/wenzhi20102321/article/details/53127914
https://www.jianshu.com/p/ca3d87a4cdf3
一般的都要在AndroidManifest中静态注册,但是只有广播接收者可以使用java代码的方法来动态注册。
BroadcastReceiver是用于接收广播的组件用于组件与组件之间进行通信,可以跨应用程序传递.如操作系统电池电量低会发送一个广播,这样我们的程序里面可以去监听这个广播,可以关 闭程序里面比较耗电的功能,提示用户注意保存进度什么的,还如其它安装新应用等,还有普通应 用程序,例如启动特定线程,文件下载完毕等。
广播的发送的一般应用场合:发送频率低的情况可以使用,数据量小的情况可以使用。
广播类型分为两种:标准广播(所有广播接收器都可以收到);有序广播(只有一个广播接收器可以收到,后面的要等一个接收器完毕才能收到,当然也可以截断后面的接收器);
接收系统广播:
注册广播接收器的方式有两种:
静态注册----在AndriodManifest.xml中指定IntentReceiver,这样在程序未启动就可以接收广播。
动态注册---在java代码中指定IntentFilt,然后添加想要的Action。程序启动后才能接收广播。
// 发送有序广播
Intent intent = new Intent();
intent.setAction("com.example.ORDERED");
sendOrderedBroadcast(intent,//意图动作,指定action动作
null, //receiverPermission,接收这条广播具备什么权限
new FinalReceiver(),//resultReceiver,最终的广播接受者,广播一定会传给他
null, //scheduler,handler对象处理广播的分发
0,//initialCode,初始代码
"初始数据!", //initialData,初始数据
null//initialExtras,额外的数据,如果觉得初始数据不够,可以通过bundle来指定其他数据
);
//发送无序列广播
//创建一个意图对象
Intent intent = new Intent();
//指定发送广播的频道
intent.setAction("com.example.BROADCAST");
//发送广播的数据
intent.putExtra("key", "发送无序广播,顺便传递的数据");
//发送
sendBroadcast(intent);
------------Mainactivity-------
public class MainActivity extends AppCompatActivity {
private ScreenBroadcast screen;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
//发自定义的无序广播
public void sendBroadcast(){
Intent intent=new Intent();
intent.setAction("custom");//这个定义的action要和清单文件中的一样
getApplicationContext().sendBroadcast(intent);//发送广播
}
//发有序广播
/*自定义广播是有优先级顺序的,有优先级大的先接受到广播,可以在接受广播后中止广播,需修改广播数据,无序的广播不可以中止广播,修改数据;
* */
public void sendOrderBroader(){
//自定义有序广播
Intent inten3=new Intent();
inten3.setAction("orderCuston");
/**
*
*参数一---------意图
* 参数二-----------------接受的权限
* 参数三---------------最终接受者,有特权,不需要在清单文件中注册,直接在参数中new 就可以了,不管前面优先级高的是不是中止了广播,他一定能收到广播
* 参数四-------------Handler
* 参数五--------------初始码
* 参数六---------------初始数据
* 参数七-------
*
*/
getApplicationContext().sendOrderedBroadcast(inten3,null,new FinalRecevier(),null,1,"有序广播",null);
}
//代码注册广播,特殊的广播接受者
public void teshuBroadcast(){
//操作频繁的广播接收者,必须用代码去注册,在清单文件中注册无效,如屏幕锁屏,解锁,电池电量变化
screen = new ScreenBroadcast();
IntentFilter filter=new IntentFilter();
filter.addAction("andriod.content.action.SCREEN_OFF");//注册action
//*****************动态注册广播接收者
registerReceiver(screen,filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消广播
unregisterReceiver(screen);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
--------------CustomBroadcast---------
public class CustomBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if("custom".equals(action)){
//自定义的无序广播
}
}
}
--------------OrderCustomBroadcast--------
public class OrderCustomBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data=getResultData();//如果在发广播的时候用的是putExtra()方法,在这里接受数据就要用intent.getExtras().get()方法
abortBroadcast();//中止广播后,优先级低的就接受不到了广播,但是发广播时设置的最终接收者还是能收到广播
setResultData("在这里修改广播数据");//修改接受到的广播数据
}
}
------------ReceiveBroadcast-------------
public class ReceiveBroadCast extends BroadcastReceiver {
//当接收到通知时调用,在清单文件中配置的Receive中的action是注册的各种广播通知,还要注意配置权限
@Override
public void onReceive(Context context, Intent intent) {
//获取当前监听的广播传递的数据
String num=getResultData();
//获取广播事件类型action
String aact = intent.getAction();
if (aact.equals("andriod.provider.TelePhony.SMS_RECEIVED")) {
//发送短息的时候接受通知,要注意在清单文件中配置schemem:file
//获取发送者的号码和手机号
Object[] objs = (Object[]) intent.getExtras().get("pdus");
for (Object obj : objs) {
SmsMessage mess = SmsMessage.createFromPdu((byte[]) obj);
String messageBody = mess.getMessageBody();//获取发送的内容
String addrss = mess.getOriginatingAddress();//获取发送的地址,手机号
}
}else if("android.intent.action.PACKAGE_ADDED".equals(aact)){
//安卓应用启动,要注意在清单文件中配置scheme:package
}else if("android.intent.action.BOOT_COMPLETED".equals(aact)){
//发的这个广播要配置权限
//手机重新启动,就显示mainactivity
Intent intent2=new Intent(context,MainActivity.class);
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//在广播中是不允许代开actiivty的,广播不在任务栈中,在这里要设置栈的标记,
context.startActivity(intent2);
}
}
}
------------清单文件中manifest.xml--------
在这里面的是静态注册广播;
<!--配置广播接收者,action是设置要监听的广播通知,可以设置多个action;在接受u通知的方法中根据获取到的action来做相应处理;
,andriod.provider.TelePhony.SMS_RECEIVED是监听短信内容的,被Google取消掉了,但是还能用;在获取sd卡操作的通知时,
要加上 <data android:scheme="file"/>这一句话;
安卓应用安装卸载的时候要加上 <data android:scheme="package"/>-->
<receiver android:name=".ReceiveBroadCast">
<intent-filter>
//监听短信
<action android:name="andriod.provider.TelePhony.SMS_RECEIVED"/>
//监听应用安装和卸载
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED"/>
//手机重新启动
<action android:name="android.intent.action.BOOT_COMPLETED"/>
" <data android:scheme="package"/>
//自定义的无序广播
<action android:name="custom"/>
</intent-filter>
</receiver>
//有序广播自定义的priority="1000"是设置优先级的,-1000到1000,1000最高
<receiver android:name=".OrderCustomBroadcast">
<intent-filter android:priority="1000">
<action android:name="orderCuston"/>
</intent-filter>
</receiver>
<receiver android:name=".TwopriorityBroadcast">
<intent-filter android:priority="100">
<action android:name="orderCuston"/>
</intent-filter>
</receiver>
//这个是读取短信的可以用但是Google 不提供了
<receiver android:name=".receiver.SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
===============打出电话的广播接收者==========
/**
* Created by wofu on 2018/4/20.
* 打出电话时的广播接受者
*/
public class PhonecallRecevier extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取拨出去的电话号码
String phone=getResultData();
//查询数据库,获取归属地----没做
}
}
<!--打出电话的广播接收者-->
<receiver android:name=".receiver.PhonecallRecevier">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
==========监听电话的状态https://blog.youkuaiyun.com/u011146511/article/details/79776597