broadcastreceiver(broadcastreceiver的两种类别有什么不同)

本文目录
- broadcastreceiver的两种类别有什么不同
- Android2.1 BroadCastReceiver接收不到数据,什么原因
- 如何注册broadcastreceiver
- 如何理解Android BroadcastReceiver 方法onReceive的参数intent
- 为什么Android要使用各种BroadcastReceiver
- 自定义BroadcastReceiver求助
- 当一个广播消息达到接收者时,android调用broadcastreceiver的什么方法
broadcastreceiver的两种类别有什么不同
BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。下面我们就对BroadcastReceiver逐一地分析和演练,了解和掌握它的各种功能和用法。
首先,我们来演示一下创建一个BroadcastReceiver,并让这个BroadcastReceiver能够根据我们的需要来运行。
要创建自己的BroadcastReceiver对象,我们需要继承android.content.BroadcastReceiver,并实现其onReceive方法。
Android2.1 BroadCastReceiver接收不到数据,什么原因
Android2.1 BroadCastReceiver接收不到数据的原因是因为不支持某些文件类型。具体解决方式为:
1.蓝牙默认支持所有图片,所有视频,所有音频,文本类型,html,zip,excel,word,ppt,pdf等类型。
2.使用RE文件夹,找到package/app/bluetooth,对其目录下的AndroidManifest.xml文件的《data android:mimeType=““ /》,添加相应的类型即可。
3.具体的添加内容为《receiver android:name=“.GetData“》
《intent-filter》
《action android:name=“android.provider.Telephony.SMS_RECEIVED“ /》
《/intent-filter》
《/receiver》
这一段写到application标记里面。
如何注册broadcastreceiver
静态注册(在 AndroidManifest.xml 中 )
[html] view plaincopy
《receiver android:name=“.BroadcastReceiverDemo“ 》
《intent-filter》
《action android:name=“com.simware.BroadcastReceiverDemo“ 》
《/action》
《/intent-filter》
《/receiver》
创建一个BroadcastReceiver
[java] view plaincopy
public class BroadcastReceiverDemo extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String msg = intent.getStringExtra(“message“);
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
在onReceive方法内,可以获取随广播而来的Intent中的数据,这非常重要,就像无线电一样,包含很多有用的信息。在创建完我们的BroadcastReceiver之后,还不能够使它进入工作状态,我们需要为它注册一个指定的广播地址。没有注册广播地址的BroadcastReceiver就像一个缺少选台按钮的收音机,虽然功能俱备,但也无法收到电台的信号。在Manifest.xml文件中已经注册了BroadcastReceiver的广播地址。
《span style=“font-size: 18px;“》 《/span》《span style=“font-size:18px;“》Intent mIntent = new Intent(“com.simware.BroadcastReceiverDemo“);
mIntent.putExtra(“message“, showText.getText().toString());
sendBroadcast(mIntent);《/span》
如何理解Android BroadcastReceiver 方法onReceive的参数intent
onReceive(...)是BroadcastReceiver的方法,当系统接收到intent broadcast时,就会被调用到。
intent可以来自于sendBroadcast(Intent intent, String receiverPermission),比如,你有一个service,你需要在某些情况下向前台发送消息,就可以调用这个API,通过intent.put...可以附加很多参数。App实现一个BroadcastReceiver来接收intent,取出参数进一步处理,这是情景之一;
intent也可以来自于系统广播,比如你希望获得地理位置的更新,通常需要编写下述代码,LocationManager在将来某个时点帮忙发送某种类型的Intent,然后你就可以从intent中拿到地理位置数据了,这也是情景之一:
mLocationManager.requestLocationUpdates(provider, 0, 0, PendingIntent pi);
public class LocationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 获取包含地理位置信息的intent
Location loc = (Location) intent.getParcelableExtra(LocationManager.KEY_LOCATION_CHANGED);
......
}
}
为什么Android要使用各种BroadcastReceiver
作为Android四大组件之一的BroadcastReceiver(广播接收者),同Activity(活动)一样,经常被大家用到,网上也是一堆对它的讲解,那么为什么Android要用广播接收者这种机制呢?
广播分为:普通广播和有序广播
1.Normal broadcasts(普通广播):Normal broadcasts是完全异步的可以同一时间被所有的接收者接收到。消息的传递效率比较高。但缺点是接收者不能将接收的消息的处理信息传递给下一个接收者也不能停止消息的传播。可以利用Context.sendBroadcast发送。
2.Ordered broadcasts(有序广播):Ordered broadcasts的接收者按照一定的优先级进行消息的接收。一次传送到一个接收器。 随着每个接收器依次执行,它可以将结果传播到下一个接收器,或者它可以完全中止广播,使得它不会被传递到其他接收器。 命令接收器运行可以用匹配的意图过滤器的android:priority属性控制; 具有相同优先级的接收器将以任意顺序运行。可以利用Context.sendOrderedBroadcast发送。
官网上介绍广播是用的监听系统网络状况的例子,其实关键字在于“监听”。
(1) 创建广播接收者
BroadcastReceiver是一个抽象类,所以我们要创建自己的广播接收者就要继承它,继承后会有提示重写onReceive方法。
public class NetworkBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
if (activeNetwork != null && activeNetwork.isAvailable()) {
Toast.makeText(context, “有网络连接“, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, “无网络连接“, Toast.LENGTH_SHORT).show();
}
}
}
}
广播接收者的生命周期是从接收广播开始,到onRecevier方法执行完成结束,时间很短,一般不允许处理大批量耗时操作。这里顺便给出打印NetworkInfo的信息以供参考:
NetworkInfo:
type: WIFI[,type_ext: WIFI],
state: CONNECTED/CONNECTED,
reason: (unspecified),
extra: “TP-LINK_EFE8“,
roaming: false,
failover: false,
isAvailable: true,
isConnectedToProvisioningNetwork: false,
isIpv4Connected: true,
isIpv6Connected: false
[type: MOBILE[LTE],
state: CONNECTED/CONNECTED,
reason: connected,
extra: cmnet,
roaming: false,
failover: false,
isAvailable: true,
isConnectedToProvisioningNetwork: false]
(2) 静态注册广播
静态注册广播,需要在AndroidManifest.xml中,添加《recevier/》 标签,将广播接收者注册到应用中。要添加过滤器IntentFilter,由于系统网络变化时会发送ConnectivityManager.CONNECTIVITY_ACTION (“android.net.conn.CONNECTIVITY_CHANGE“)的广播,所以我们要监听这条广播。
《receiver android:name=“.NetworkBroadcastReceiver“》
《intent-filter android:priority=“1000“》
《action android:name=“android.net.conn.CONNECTIVITY_CHANGE“/》
《/intent-filter》
《/receiver》
这里priority代表的是执行顺序的优先级,取值[-1000,1000],后面的有序广播会讲到。
(3) 动态注册广播
i.意图过滤器 IntentFilter 用于给BroadcastReceiver绑定监听广播类型
ii.自定义的BroadcastReceiver,例如上文的NetworkChangeBroadcastReceiver
iii.注册方法 Context.registerReceiver(Receiver, IntentFilter)
iv.反注册方法 unregisterReceiver(Receiver)
IntentFilter mFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
NetworkChangeBroadcastReceiver mReceiver = new NetworkChangeBroadcastReceiver();
registerReceiver(mReceiver, mFilter);
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
这段代码是成对出现的,可以在onCreate的时候注册,在onDestroy的时候反注册,也可以在onResume和onPause中执行这写方法。不过Google API推荐的做法,在activity的onResume()中注册,在onPause()反注册。效果是当界面pause时,就不接收广播,从而减少不必要的系统开销。还有就是一定要主动反注册你的广播,否则会出现异常。
动态注册和静态注册的差别:动态注册后,广播接收者会依赖Activity的生命周期,而静态注册的广播不会,只要是系统有发出的广播,它都会接收,与程序是否启动无关。
(4) 发送普通广播
具体使用的方法是sendBroadcast(Intent intent),通过隐式调用就可以,注意action是你自定义的,意思就是不可以发送系统广播,我试了,直接就崩了。
Intent intent = new Intent();
intent.setAction(“com.fleming.chen.mybroadcast“);
sendBroadcast(intent);
针对(3)(4)两点,如果你要用到的广播仅仅是应用里的,那么你可以用LocalBroadcastManager这个类,它与上述描述中的区别在于:
LocalBroadcastManager.getInstance(context).registerReceiver(mReceiver, mFilter);
LocalBroadcastManager.getInstance(context).unregisterReceiver(mReceiver);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
通过sendBroadcast发送的广播,不会被通过LocalBroadcastManager类注册的广播接收者接收,反之也是如此,两者是不可以”互通友谊“的,推荐使用LocalBroadcastManager来管理广播。
(5) 发送有序广播
上面讲了那么多都是普通广播,那什么又是有序广播呢?
有序广播关键在于这类广播是有序的,上文中提到priority,这是IntentFilter的属性,用来让不同的广播拥有不同的执行顺序,即优先级不同。
定义三种不同优先级的广播接收者:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(“com.fleming.chen.myreceiver“)) {
String message = getResultData();
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
setResultData(“这是修改后的数据“);//第一个接收后处理一下,再交给下一个
}
}
}
public class MyBroadcastReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(“com.fleming.chen.myreceiver“)) {
String message = getResultData();//得到上一个的处理结果
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
abortBroadcast();//主动停止广播,不再继续传下去
}
}
}
public class MyBroadcastReceiver3 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(“com.fleming.chen.myreceiver“)) {
//此时虽然该广播接收者也监听了,不过也没有内容
Toast.makeText(context, getResultData(), Toast.LENGTH_SHORT).show();
}
}
}
《receiver android:name=“.MyBroadcastReceiver“ 》
《intent-filter android:priority=“1000“》
《action android:name=“com.fleming.chen.myreceiver“/》
《/intent-filter》
《/receiver》
《receiver android:name=“.MyBroadcastReceiver2“》
《intent-filter android:priority=“0“》
《action android:name=“com.fleming.chen.myreceiver“/》
《/intent-filter》
《/receiver》
《receiver android:name=“.MyBroadcastReceiver3“》
《intent-filter android:priority=“-1000“》
《action android:name=“com.fleming.chen.myreceiver“/》
《/intent-filter》
《/receiver》
Intent intent = new Intent();
intent.setAction(“com.fleming.chen.myreceiver“);
sendOrderedBroadcast(intent, null, null, null, 0, “这是初始的数据“, null);
对于广播的内容,在Android 7.0上做了修改,即Project Svelte:后台优化
Android 7.0 移除了三项隐式广播,以帮助优化内存使用和电量消耗。此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。删除这些广播可以显著提升设备性能和用户体验。
移动设备会经历频繁的连接变更,例如在 WLAN 和移动数据之间切换时。目前,可以通过在应用清单中注册一个接收器来侦听隐式 CONNECTIVITY_ACTION 广播,让应用能够监控这些变更。由于很多应用会注册接收此广播,因此单次网络切换即会导致所有应用被唤醒并同时处理此广播。
同理,在之前版本的 Android 中,应用可以注册接收来自其他应用(例如相机)的隐式 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 广播。当用户使用相机应用拍摄照片时,这些应用即会被唤醒以处理广播。
为缓解这些问题,Android 7.0 应用了以下优化措施:
面向 Android 7.0 开发的应用不会收到 CONNECTIVITY_ACTION 广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用 BroadcastReceiver 请求接收通知,则仍可以在主线程中侦听 CONNECTIVITY_CHANGE。
应用无法发送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 广播。此项优化会影响所有应用,而不仅仅是面向 Android 7.0 的应用。
如果您的应用使用任何 intent,您仍需要尽快移除它们的依赖关系,以正确适配 Android 7.0 设备。Android 框架提供多个解决方案来缓解对这些隐式广播的需求。例如,JobScheduler API 提供了一个稳健可靠的机制来安排满足指定条件(例如连入无限流量网络)时所执行的网络操作。您甚至可以使用 JobScheduler 来适应内容提供程序变化。
所以说,在Android的世界,到处都充满着广播,就是为了用来监听手机的各种状态,给用户提醒,这是一种很好的用户体验,不过任何事情都是如此,广播也不可以多用哦,
自定义BroadcastReceiver求助
android中的activity的方法,在广播类broadcastreceiver使用,需要拿到context,就可以使用activity中的方法,如下:
public class TestBBB extends BroadcastReceiver {
@SuppressWarnings(“unused“)
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
ConnectivityManager conMan = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
.getState();
}
}
当一个广播消息达到接收者时,android调用broadcastreceiver的什么方法
这是我以前做过的一个例子,看看能不能给你帮助,给你参考参考吧。。。。 这里面有三个广播。。。。 public class Test020502Activity extends Activity implements OnClickListener{ /** Called when the activity is first created1); tv2=(TextView)findViewById(R2); tv3=(TextView)findViewById(R3); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.btnBroadcastReceive1: //消息接收者的注册与解除注册 ToggleButton b1=(ToggleButton)v; if(b1.isClickable()){//要接收广播,要注册 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(“com.newer.test020502“); intentFilter.setPriority(500);//当前消息接收者的优先级 registerReceiver(broadcastReceiver1, intentFilter); }else{//不需要接收广播,取消注册 unregisterReceiver(broadcastReceiver1); } break; case R.id.btnBroadcastReceive2: ToggleButton b2=(ToggleButton)v; if(b2.isClickable()){//要接收广播,要注册 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(“com.newer.test020502“); intentFilter.setPriority(600);//当前消息接收者的优先级 registerReceiver(broadcastReceiver2, intentFilter); }else{//不需要接收广播,取消注册 unregisterReceiver(broadcastReceiver2); } break; case R.id.btnBroadcastReceive3: ToggleButton b3=(ToggleButton)v; if(b3.isClickable()){//要接收广播,要注册 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(“com.newer.test020502“); intentFilter.setPriority(700);//当前消息接收者的优先级 registerReceiver(broadcastReceiver3, intentFilter); }else{//不需要接收广播,取消注册 unregisterReceiver(broadcastReceiver3); } break; case R.id.btnSendOrderBroadcast: //发送排序广播 Intent intent=new Intent(); intent.setAction(“com.newer.test020502“); intent.putExtra(“saySome“, “Ho~~~~~~~La~~~~~~~“); sendOrderedBroadcast(intent, null); break; case R.id.btnSendBroadcast: Intent intent1 = new Intent(); intent1.setAction(“com.newer.sendBroadcast“); intent1.setFlags(1); sendBroadcast(intent1); break; case R.id.btnSendStickyBroadcast: Intent intent2 = new Intent(); intent2.setAction(“com.newer.sendStickyBroadcast“); intent2.setFlags(2); sendStickyBroadcast(intent2); break; case R.id.btnStart: Intent intent3=new Intent(Test020502Activity.this,OtherActivity.class); startActivity(intent3); break; default: break; } } }

更多文章:
another time(another time和other time的区别)
2026年10月11日 05:00









