注册广播有2种方式
1.代码注册(动态注册)
2.在AndroidManifest.xml注册(静态注册)
动态注册
MainActivity.java
public class MainActivity extends Activity {
NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter =new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//网络状态发生变化的广播
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);//注册
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);//解除注册
}
public class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo =connectivityManager.getActiveNetworkInfo();
if(networkInfo!=null&&networkInfo.isAvailable()){
Toast.makeText(context, "network is available", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(context, "network is unavailable", Toast.LENGTH_LONG).show();
}
}
}
查询网络连接的状态必须要在AndroidManifest.xml中注册
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
当网络连接状态发生改变的时候
静态注册
新建一个BootCompleteReceiver.java
package com.example.broadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class BootCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context,"BootComplete", Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED">
<!--接收开机启动广播的权限-->
</uses-permission>
<application>
<receiver android:name="com.example.broadcastReceiver.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<!--开机启动的广播-->
</intent-filter>
</receiver>
</application>
效果:
自定义发送广播
使用静态的方式先注册广播
<receiver
android:name="com.example.broadcastReceiver.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.MyBroadcastReceiver"/>
</intent-filter>
</receiver>
MyBroadcastReceiver.java(广播接收器类)
package com.example.broadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context,"mybroadcastReceiver", Toast.LENGTH_SHORT).show();
}
}
在MainActivity发送广播
Button btn_sent =(Button) this.findViewById(R.id.sendBroadcast);
btn_sent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent("android.intent.action.MyBroadcastReceiver");
sendBroadcast(intent);
}
});
效果
广播可以用于应用程序之间的通信。
在另一个app内也静态的注册一个广播接收器,接收的广播为第一个app发送的广播。
有序广播
在原来
Intent intent = new Intent("android.intent.action.MyBroadcastReceiver");
sendBroadcast(intent);
改为
sendOrderedBroadcast(intent, null);
当广播为有序广播时,要为广播接收器设定优先级
android:priority=”100”
<receiver
android:name="com.example.broadcastReceiver.MyBroadcastReceiver">
<intent-filter android:priority="100">
<action android:name="android.intent.action.MyBroadcastReceiver"/>
</intent-filter>
</receiver>
有序广播可以被切断
当广播被此广播接收器接收后,广播被切断
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context,"mybroadcastReceiver", Toast.LENGTH_SHORT).show();
abortBroadcast();//切断广播
}
}
上方的广播属于全局广播,存在安全性问题,广播有可能被别的程序截获,别的程序也可以不断的向我们的程序发送垃圾广播,因此引入本地广播
本地广播
本地广播使用的是动态注册,因为既然是在app内传播,app当然已经启动了,所以不使用静态注册是可以理解的(不能静态注册)
MainActivity.java
LocalReceiver localReceiver;
LocalBroadcastManager localBroadcastManager;
{
localBroadcastManager = LocalBroadcastManager.getInstance(this);//实例一个本地广播管理者
IntentFilter inteFilter = new IntentFilter(); inteFilter.addAction("android.intent.action.LoaclBroadcast");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,inteFilter);//注册本地广播监听器
Button btn_sent =(Button) this.findViewById(R.id.sendBroadcast);
btn_sent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent("android.intent.action.LoaclBroadcast");
localBroadcastManager.sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);//解除注册
}
public class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context, "localBroadcast", Toast.LENGTH_SHORT).show();
}
}
效果
在广播接受器弹出窗口
package com.example.broadcastReceiver;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.WindowManager;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
AlertDialog.Builder ab =new AlertDialog.Builder(context);
ab.setTitle("hello world!");
ab.setCancelable(false);//不可以取消
ab.setMessage("ni hao!");
ab.setPositiveButton("ok",null);
AlertDialog alertDialog = ab.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//系统级别的弹出窗口
//是TYPE_SYSTEM_ALERT而不是TYPE_SYSTEM_DIALOG
alertDialog.show();
}
}
声明权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>
效果
2015/12/27 更新
(讨论的是动态注册)
在活动创建的时候注册广播,在活动销毁的时候销毁广播。
即一个活动没有被创建就不会收到广播,之前发的广播不会在活动启动后接收到。
必须在活动存活的时候发送广播,活动才能接收到。
如果有多个活动同时接受一个广播,并且这些活动都是存活的,那么它们都可以接收到广播。接收的顺序按栈向上的顺序,即在底层的活动会先接收到。
项目中的使用广播的格式
定义一个Broadcast类,专门为APP注册和销毁广播
package com.example.broadcast;
import com.example.testbroadcast1227.MyApp;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class MyBroadcast {
public static String BROADCAST = "broadCast";
public static String BROADCAST2 = "broadCast2";
/**
* 注册广播接收者
*/
public static void registerBroadcastReceiver(String action,BroadcastReceiver receiver) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(action);
MyApp.getContext().registerReceiver(receiver, intentFilter);
//这里的MyApp.getContext()返回的是 继承Application类的context
}
public static void registerBroadcastReceiver(String [] actions,BroadcastReceiver receiver) {
IntentFilter intentFilter = new IntentFilter();
for (String action : actions) {
intentFilter.addAction(action);
}
MyApp.getContext().registerReceiver(receiver, intentFilter);
}
/**
* 销毁广播接收者
*/
public static void unregisterBroadcastReceiver(BroadcastReceiver receiver) {
MyApp.getContext().unregisterReceiver(receiver);
}
/**
* 发广播
*/
public static void sendBroadcastAction(String action){
sendBroadcastAction(action, null);
}
public static void sendBroadcastAction(String action,Bundle bundle){
Intent intent = new Intent(action);
if (bundle != null) {
intent.putExtras(bundle);
}
MyApp.getContext().sendBroadcast(intent);
}
}
在具体的活动中用法:
MainActivity.java
package com.example.testbroadcast1227;
import com.example.broadcast.MyBroadcast;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private BroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerBroadcast();
Button bt = (Button) findViewById(R.id.bt_sendBroadcast);
bt.setOnClickListener(this);
Button bt2 = (Button) findViewById(R.id.bt_intoAct2);
bt2.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterBroadcast();
}
private void registerBroadcast() {
if (receiver == null) {
receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MyBroadcast.BROADCAST)) {
Log.v("TAG", "1:broadcast");
}
else if (intent.getAction().equals(MyBroadcast.BROADCAST2)) {
Log.v("TAG", "1:broadcast2");
}
}};
}
MyBroadcast.registerBroadcastReceiver(new String[] {
MyBroadcast.BROADCAST,
MyBroadcast.BROADCAST2 }, receiver);
}
private void unregisterBroadcast() {
MyBroadcast.unregisterBroadcastReceiver(receiver);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_sendBroadcast:
MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST);
break;
case R.id.bt_intoAct2:
//跳转
Act2.show(this);
break;
}
}
}
Act2.java
package com.example.testbroadcast1227;
import com.example.broadcast.MyBroadcast;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Act2 extends Activity implements OnClickListener{
BroadcastReceiver receiver;
public static void show(Context context) {
Intent intent = new Intent(context,Act2.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act2);
registerBroadcast();
Button bt2 = (Button) findViewById(R.id.bt_sendBroadcast2);
bt2.setOnClickListener(this);
Button bt1 = (Button) findViewById(R.id.bt_sendBroadcast1);
bt1.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterBroadcast();
}
private void registerBroadcast() {
if (receiver == null) {
receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MyBroadcast.BROADCAST)) {
Log.v("TAG", "2:broadcast");
}
else if (intent.getAction().equals(MyBroadcast.BROADCAST2)) {
Log.v("TAG", "2:broadcast2");
}
}};
}
MyBroadcast.registerBroadcastReceiver(new String[] {
MyBroadcast.BROADCAST,
MyBroadcast.BROADCAST2 }, receiver);
}
private void unregisterBroadcast() {
MyBroadcast.unregisterBroadcastReceiver(receiver);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_sendBroadcast2:
MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST2);
break;
case R.id.bt_sendBroadcast1:
MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST);
break;
}
}
}
在MainActvity点击按钮发送广播:
只有MainActivity能接到广播
在Act2的2个按钮分别发送广播:
可以看到2个活动都收到广播,并且是MainActivity先收到,Act2后收到
2016/01/27更新
1.开机广播
<action android:name="android.intent.action.BOOT_COMPLETED"/>
在4.42 (T1),4.4.4(小米平板1) 测试均无法接收
2.app如果被杀死(Back键退出不算),将无法接收到广播
2016/3/25 更新
广播接收器注册一共有两种形式 : 静态注册和动态注册.
两者及其接收广播的区别:
1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低>\
2.动态注册广播不是 常驻型广播 ,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。
静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
3.在同一个优先级下,谁先启动的快,谁将先接收到广播.