您的位置:首页 > 其它

广播接收者(Broadcast Receiver)

2016-08-23 11:06 357 查看
独立寒秋,湘江北去,橘子洲头。 —–毛泽东《沁园春·长沙》

广播
广播类型
有序广播

无序广播

特殊的广播接收者

注册广播接收者的两种方式

系统广播示例
接收系统发送的广播
示例-短信到来

自定义无序广播示例
创建广播

接收广播方式静态注册

接收广播方式代码注册

自定义有序广播示例
发送有序广播

接收有序广播

有序广播结果

特殊的广播接收者-锁屏等等

广播

听广播要有:电台 收音机 音乐广播

Android系统内部已经定义好了电台 ,也已经定义好了一些广播事件

比如外拨电话 短信到来 SD卡状态 电池电量….

使用Broadcast Receiver取接收系统已经定义好的事件

定义广播是为了开发者更好的开发

发送方和接收发可以是同一个应用程序

广播接收器没有用户界面

如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由Service 来完成

广播类型

有序广播

按照一定的优先级接收

发送优先级级别数值是在 -1000 到 1000 之间 , 值越大 , 发送的优先级越高

有序广播的数据可以被修改

有序广播的数据可以被终止

无序广播

无序广播的数据不可以被修改

无序广播的数据不可以被终止

特殊的广播接收者

操作特别频繁的广播事件,比如屏幕的锁屏和解锁,电池电量的变化 这种事件的广播在清单文件里面注册无效

SD卡的安装,卸载的广播,想要接收的话,需要一个约束类型,在< receiver>中

<receiver android:name="....">
<intent-filter>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"></action>
<action android:name="android.intent.action.MEDIA_MOUNTED"></action>
<!--约束类型叫file sd卡的数据类型是file -->
<data android:scheme="file"></data>
</intent-filter>
</receiver>


应用程序的安装,卸载 也需要一个约束类型

<data android:scheme="package"></data>


注册广播接收者的两种方式

注意

动态注册,广播接收者的生命周期依附应用程序的生命,关闭程序,广播接收者也无效了

在清单文件里注册,广播接收者的生命会依附应用程序的进程存在,即使关闭了应用程序,进程没有销毁(没有因为内存不足销毁),广播接收者也是有效的

[1]动态注册 通过代码方式注册

private MyBroadcast myBroadcast;
......
myBroadcast = new MyBroadcast();

IntentFilter filter =new IntentFilter();
filter.addAction("......");
registerReceiver(myBroadcast,filter);


public  class MyBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//接收广播后执行逻辑
}
}


@Override
protected void onDestroy() {
unregisterReceiver(screenReceiver);
super.onDestroy();
}


[2]在清单文件里通过receiver tag 节点静态发布

<receiver android:name=".SmsListenerReciver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>


系统广播示例

接收系统发送的广播

[1] 定义广播接收者

public class onReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}


[2]在清单文件里配置

<receiver android:name=".SmsListenerReciver"/>


[3定义过滤器具体接收什么广播

<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>


示例-短信到来

短信到来是一个有序广播

定义广播接收者

package com.peng.smslistener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;

/**
* Created by Peng on 2016/7/31.
*/
public class SmsListenerReciver  extends BroadcastReceiver{
//短信到来是执行
@Override
public void onReceive(Context context, Intent intent) {

System.out.println("短信到了");
//拿到信息发送的内容和号码
Object object[] = (Object[]) intent.getExtras().get("pdus");

//循环取短信
for(Object obj:object){
//获取smsmessage实例
SmsMessage smsMessage= SmsMessage.createFromPdu((byte[]) obj);
//获取发送短信的内容
String messageBody = smsMessage.getMessageBody();
String address = smsMessage.getOriginatingAddress();

System.out.println("body:"+messageBody+address);
}

}
}


配置广播接收者

<receiver android:name=".SmsListenerReciver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
...
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>


自定义无序广播示例

发送广播和接收广播在不同的两个应用程序中

创建广播

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View view) {
//发送无序广播
Intent intent =new Intent();
intent.setAction("com.peng.guangbo");

intent.putExtra("name","新闻联播每天晚上7点准时开播");

sendBroadcast(intent);
System.out.println("--------------->>>>>>>发送无序广播");
}
}


接收广播方式(静态注册)

public class onReceiver extends BroadcastReceiver {

//接收自定义广播
@Override
public void onReceive(Context context, Intent intent) {
//终止广播,在无序广播里没用
abortBroadcast();
String content =intent.getStringExtra("name");

Toast.makeText(context,content,Toast.LENGTH_LONG).show();
}
}


<receiver android:name="定义的接收者类名">
<intent-filter>
<action android:name="com.peng.guangbo"></action>
</intent-filter>
</receiver>


接收广播方式(代码注册)

有序和无序广播都可以通过代码注册

public class MainActivity extends AppCompatActivity {

private Mybroadcastreceiver receiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new Mybroadcastreceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.peng.guangbo");
registerReceiver(receiver,filter);
}
public class Mybroadcastreceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String content =intent.getStringExtra("name");
System.out.println(">>>>>>>>>>>动态注册");
Toast.makeText(context,content, Toast.LENGTH_LONG).show();
}
}

@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}


自定义有序广播示例

发送广播和接收广播在不同的两个应用程序中

发送有序广播

假定”政府”发送一个广播,并携带数据”政府给每个村民发了1000元补贴”,这里设置了四个接收者,分别是”省长”,”市长”,”乡长”,和”农民”,优先级级别从高到低,并且会更改数据

public void click(View view) {
//点击按钮发送有序广播
Intent intent = new Intent();
intent.setAction("com.peng.sendrice");
/**
*
* 1 Intent 意图
* 2 receiverPermission 接收的权限
* 3 resultReceiver 最终的receiver
* 4 scheduler handler
* 5 initialcode 初始码
* 6initalDate 初始化数据
*/
sendOrderedBroadcast(intent,null,new FinalReceiver(),null,1,"政府给每个村民发了1000元补贴",null);
}


FinalReceiver 位于发送广播的应用程序中

这是一个resultReceiver,也是一个广播接收者,也可以理解为finalReceiver,当广播被所有接收方接收之后,才会执行这个广播接收者,相当于广播结果的反馈,它返回的是最后一个广播接收者接收的内容,在这个例子中就是”农民”的接收的数据

public class FinalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

String content = getResultData();

Toast.makeText(context,"报告习大大:"+content,Toast.LENGTH_LONG).show();

}
}


接收有序广播

在清单文件里配置过滤器,接收方分别新建一个类,便于管理



如果你想在MainActivity里写广播接收者,又想在清单文件里配置,就会是这样,

<receiver android:name=".MainActivity$Mybroadcastreceiver"></receiver>


“省长”

public class ProvienceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

String content = getResultData();

Toast.makeText(context,"省长:"+content,Toast.LENGTH_LONG).show();
/*
*//终止广播
*abortBroadcast();
*/
//修改广播
setResultData("政府给每个村民发了500元补贴");

}
}


“市长”

public class CityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

String content = getResultData();

Toast.makeText(context,"市长:"+content,Toast.LENGTH_LONG).show();
//修改广播
setResultData("政府给每个村民发了250元补贴");
}
}


“乡长”

public class CountryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

String content = getResultData();

Toast.makeText(context,"乡长:"+content,Toast.LENGTH_LONG).show();
//修改广播
setResultData("政府给每个村民发了50元补贴");
}
}


“农民”

public class NongMinReceiver  extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {

String content = getResultData();

Toast.makeText(context,"农民:"+content,Toast.LENGTH_LONG).show();
}
}


清单文件里配置< reeiver>和优先级

如果通过代码注册,优先级可以这样设置

IntentFilter intentFilter =new IntentFilter();
intentFilter.addAction("......");
intentFilter.setPriority(100);


清单文件里配置

<receiver android:name=".ProvienceReceiver">
<!-- 省长-->
<intent-filter android:priority="1000">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
<!-- 市长-->
<receiver android:name=".CityReceiver">
<intent-filter android:priority="500">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
<!-- 乡长-->
<receiver android:name=".CountryReceiver">
<intent-filter android:priority="100">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
<!-- 农民-->
<receiver android:name=".NongMinReceiver">
<intent-filter android:priority="-100">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>


有序广播结果



特殊的广播接收者-锁屏等等

MainActivity.java

.....
public class MainActivity extends AppCompatActivity {
private ScreenReceiver screenReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//动态的注册广播接收者
screenReceiver = new ScreenReceiver();
/*<intent-filter>
<action android:name="android.intent.action.SCREEN_ON"></action>
<action android:name="android.intent.action.SCREEN_OFF"></action>
</intent-filter>*/

//创建intentfilter对象
IntentFilter intentFilter =new IntentFilter();

//添加要注册的action
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.SCREEN_OFF");
//动态的注册广播接收者
registerReceiver(screenReceiver,intentFilter);

}

@Override protected void onDestroy() { unregisterReceiver(screenReceiver); super.onDestroy(); }
}


ScreenReceiver.java

.....
public class ScreenReceiver extends BroadcastReceiver {
//当我们屏幕解锁和锁屏 这个方法执行
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的事件类型
String action = intent.getAction();
if("android.intent.action.SCREEN_OFF".equals(action)) {
System.out.println("屏幕锁屏了");
}else if("android.intent.action.SCREEN_ON".equals(action)){
System.out.println("屏幕解锁了");
}
}
}


屏幕都关了,就不要用Toast显示屏幕锁屏数据了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  broadcast