-、BroadcastReceivcer概述
1、什么是广播
2、BroadcastReceiver的创建启动
BroadcastReceiver是用用于接受程序所放出的Broadcast Intent,与应用程序启动的Activity、Service相同。也只需要两步:
①、创建需要启动的Broadcast的Intent
②、创建一个类继承BroadcastReceiver,在清单文件中注册Receiver,调用content的SendBroadcast()或sendOrderedBroadcast()(发送有序广播)的方法来启动指定的BroadcastReceiver
注:当应用程序发出一个Broadcast Intent之后,所有匹配该Intent的BroadcastReceiver都会启动。如果你不需要发送广播跨应用程序,考虑使用 这类 LocalBroadcastManager
1
2
3
4
5
6
7
8
9
10
11
12
13
|
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_startbroadcast = (Button)
this
.findViewById(R.id.bt_startbroadcast);
bt_startbroadcast.setOnClickListener(
new
View.OnClickListener() {
public
void
onClick(View v) {
Intent intent =
new
Intent(MainActivity.
this
, myBroadcast.
class
);
intent.putExtra(
"broadcast"
,
"hello,world! broadcast"
);
sendBroadcast(intent);
}
});
}
|
1
2
3
|
public
void
onReceive(Context context, Intent intent) {
Toast.makeText(context,
"receiver-----"
+ intent.getStringExtra(
"broadcast"
),
1
).show();
}
|
3、有序广播
-
正常播放 (发送 Context.sendBroadcast )是完全异步的。 所有的BroadcastReceiver是运行在一个未定义的顺序,常常在同一时间。 这时效率更高,但是意味着BroadcastReceiver器,不能使用结果或中止 。
-
有序广播 (发送 Context.sendOrderedBroadcast )交付给一个BroadcastReceiver。 因为每个BroadcastReceiver执行后返回值,它可以传播到下一个BroadcastReceiver,也可以完全通过abortBroadcast()方法终止广播,这样它就不会通过再通过后面的BroadcastReceiver两人。 在清单文件中可以控制运行 android:priority="" 的属性匹配intent-filter;BroadcastReceiver相同的优先级将运行在一个任意的顺序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
class
MainActivity
extends
Activity {
private
Button bt_start;
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_start = (Button)
this
.findViewById(R.id.bt_start);
bt_start.setOnClickListener(
new
View.OnClickListener() {
public
void
onClick(View v) {
Intent intent =
new
Intent();
intent.setAction(
"abc"
);
intent.putExtra(
"name"
,
"hello,BroadcastReceivcer"
);
sendBroadcast(intent);
}
});
}
|
1
2
3
4
|
public
void
onReceive(Context arg0, Intent intent) {
String name = intent.getStringExtra(
"name"
);
System.out.println(
"one======="
+ name);
}
|
1
2
3
4
5
|
<
receiver
android:name
=
"com.example.broadcast_order.One"
>
<
intent-filter
android:priority
=
"10"
>
<
action
android:name
=
"abc"
/>
</
intent-filter
>
</
receiver
>
|
1
2
3
4
5
6
7
8
|
public
class
Two
extends
BroadcastReceiver {
public
void
onReceive(Context arg0, Intent intent) {
String name = intent.getStringExtra(
"name"
);
System.out.println(
"Two======="
+ name);
// 取消Broadcast继续传递
abortBroadcast();
}
}
|
1
2
3
4
5
|
<
receiver
android:name
=
"com.example.broadcast_order.Two"
>
<
intent-filter
android:priority
=
"12"
>
<
action
android:name
=
"abc"
/>
</
intent-filter
>
</
receiver
>
|
二、Receiver的生命周期
由于BroadcastReceiver本质上属于一个监听器,因此实现BroadcastReceiver的方法也十分简单,只要重写BroadcastReceiver方法中的onReceiv(Content content,Intent intent)方法即可。
每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver的实例,并且自动触发他的onReceive()方法,onReceive()方法执行完后,Broadcast的实例就会被销毁。也就是说Broadcast的生命周期就是onReceive()这个方法。
如果Broadcast的onReceive()方法不能在10秒内执行完成,Android会认为该程序无响应。所以不要在BroadcastReceiver的onReceive()方法中执行一些耗时操作,否则会弹出ANR的对话框。若必须要执行比较耗时的操作,则要考虑Intent的启动一个Service来完成操作。不应该考虑使用新线程去完成耗时的操作,因为BroadcastReceiver的生命周期太短了。
三、Receiver实现电池电量监控
1
2
3
4
5
6
7
8
9
10
11
12
13
|
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_startbroadcast = (Button)
this
.findViewById(R.id.bt_startbroadcast);
bt_startbroadcast.setOnClickListener(
new
View.OnClickListener() {
public
void
onClick(View v) {
// 指定Broadcast能匹配Intent的方法有两种,一种是清单文件中写配置,一种是代码指定如下
IntentFilter filter =
new
IntentFilter(Intent.ACTION_BATTERY_CHANGED);
myBroadcast receiver =
new
myBroadcast();
// new出自定义BroadcastReceiver的类
registerReceiver(receiver,filter);
}
});
}
|
1
2
3
4
5
6
7
8
|
public
void
onReceive(Context context, Intent intent) {
if
(intent.getAction().equals(intent.ACTION_BATTERY_CHANGED)) {
// 获取当前电量
int
level = intent.getIntExtra(
"level"
,
0
);
// 获取总的电量
int
scale = intent.getIntExtra(
"scale"
,
100
);
Toast.makeText(context,
"电池电量为:"
+ ((level *
100
) / scale) +
"%"
,
1
).show();
}
|
注意要在清单文件中添加获取电量权限状态的权限: <uses-permission android:name="android.permission.BATTERY_STATS"/>
四、开机自动运行
在自定义的BroadcastReceiver中启动activities或Service
1
2
3
4
5
|
public
void
onReceive(Context context, Intent intent) {
Intent intent1 =
new
Intent(context, BootActivity.
class
);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //注册Activity时要使用setFlag()。Service不用
context.startActivity(intent1);
}
|
清单文件中注册Receiver
1
2
3
4
5
6
|
<
receiver
android:name
=
"com.example.BroadcastReceiverDemo.myBroadcast"
>
<
intent-filter
>
<
action
android:name
=
"android.intent.action.BOOT_COMPLETED"
/>
<
category
android:name
=
"android.intent.category.HOME"
/>
</
intent-filter
>
</
receiver
>
|
增加开机访问的权限:<uses-permission android:name="android.permission.BATTERY_STATS" />