BroadcastReceiver 原理推荐看这篇博客:http://yangguangfu.iteye.com/blog/1063732
有一部分实例参考了这篇博客http://blog.csdn.net/qq_26787115/article/details/51113053
最全实例,请看本文。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cctvjiatao.broadcastreceiverdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="21" />
<!-- 监听收发短信的权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- 监听网络连接状态的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 监听拨手机号码的权限 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<!-- 监听开机状态的权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 静态广播 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.StaticAction" >
<intent-filter>
<action android:name="com.action.static" />
</intent-filter>
</receiver>
<!-- 系统广播:监听短信 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.SystemAction" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<!-- 系统广播:监听网络连接状态 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.System2Action" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<!-- 系统广播:监听拨号 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.System3Action" >
<intent-filter>
<action android:name="android.net.conn.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<!-- 系统广播:拦截指定号码的短信 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.System4Action" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<!-- 系统广播:监听SD卡 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.System5Action" >
<intent-filter>
<!-- SD卡就绪广播 -->
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<!-- SD卡拔出广播 -->
<action android:name="android.intent.action.MEDIA_REMOVED" />
<!-- SD卡卸载广播 -->
<action android:name="android.intent.action.MEDIA_UNMOUNTABLE" />
<data android:scheme="file" />
</intent-filter>
</receiver>
<!-- 系统广播:监听开机状态 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.System6Action" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- 系统广播:监听应用安装卸载 -->
<receiver android:name="com.cctvjiatao.broadcastreceiverdemo.System7Action" >
<intent-filter>
<!-- 安装应用 -->
<action android:name="android.intent.action.PACKAGE_ADDED" />
<!-- 更新应用 -->
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<!-- 卸载应用 -->
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<!-- 携带包名 -->
<data android:scheme="package" />
</intent-filter>
</receiver>
<!-- 有序广播1 -->
<receiver android:name=".OrderReceiverOne" >
<intent-filter android:priority="1000" >
<action android:name="com.action.order" />
</intent-filter>
</receiver>
<!-- 有序广播2 -->
<receiver android:name=".OrderReceiverTwo" >
<intent-filter android:priority="600" >
<action android:name="com.action.order" />
</intent-filter>
</receiver>
<!-- 有序广播3 -->
<receiver android:name=".OrderReceiverThree" >
<intent-filter android:priority="300" >
<action android:name="com.action.order" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java
import com.cctvjiatao.broadcastreceiverdemo.R;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 上午8:17:20
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:MainActivity.java
* @版权声明:www.cctvjiatao.com
* @功能: BroadcastReceiver 静态广播、动态广播、系统广播、有序广播
* 原理详见:http://yangguangfu.iteye.com/blog/1063732
*/
public class MainActivity extends Activity {
private final String TAG = getClass().getSimpleName() ;
private ListView lv_list;
private ArrayAdapter<String> mArrayAdapter;
private String[] strList;
private static final String STATICACTION = "com.action.static";
private static final String DYNAMICACTION = "com.action.dynamic";
private static final String ORDERACTION = "com.action.order";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initAdapter();
initView();
IntentFilter filter = new IntentFilter();
filter.addAction(DYNAMICACTION);
registerReceiver(dynamicReceiver, filter);
}
private void initAdapter() {
strList = new String[]{"发送静态注册广播消息","发送动态注册广播消息","有序广播"};
mArrayAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, strList);
}
private void initView() {
lv_list = (ListView) findViewById(R.id.lv_list);
lv_list.setAdapter(mArrayAdapter);
lv_list.setOnItemClickListener(listenerBroadcastReceiver);
}
private OnItemClickListener listenerBroadcastReceiver = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Toast.makeText(MainActivity.this, strList[position], 1000).show();
switch(strList[position]){
case "发送静态注册广播消息":
Log.e(TAG, "发送静态注册广播消息");
Intent intentStatic = new Intent();
intentStatic.setAction(STATICACTION);
intentStatic.putExtra("msg", "接收静态注册广播消息成功");
sendBroadcast(intentStatic);
break;
case "发送动态注册广播消息":
Log.e(TAG, "发送动态注册广播消息");
Intent intentDynamic = new Intent(DYNAMICACTION);
intentDynamic.putExtra("msg", "接收动态注册广播消息成功");
sendBroadcast(intentDynamic);
break;
case "有序广播":
Log.e(TAG, "有序广播");
Intent intentOrder = new Intent(ORDERACTION);
/*上面这行,等同于下面这两行
Intent intentOrder = new Intent();
intentOrder.setAction(ORDERACTION);*/
sendOrderedBroadcast(intentOrder, null, null, null, 0, "自定义广播内容", null);
break;
default:
break;
}
}
};
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(dynamicReceiver);
};
private BroadcastReceiver dynamicReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(DYNAMICACTION)) {
String msg = intent.getStringExtra("msg");
Toast.makeText(context, msg, 5000).show();
}
}
};
/**
* 重写onBackPressed()方法,是返回键无效,配合System6Action可实现流氓软件
*/
/*@Override
public void onBackPressed() {
//禁止返回键
// super.onBackPressed();
}*/
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.cctvjiatao.broadcastreceiverdemo.MainActivity" >
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
StaticAction.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 上午8:17:20
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:StaticAction.java
* @版权声明:www.cctvjiatao.com
* @功能: 当出发静态广播按钮时时,会启动本类
*/
public class StaticAction extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("msg");
Toast.makeText(context, msg, 5000).show();
}
}
SystemAction.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 上午8:17:20
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:SystemAction.java
* @版权声明:www.cctvjiatao.com
* @功能: 当手机收到短信时,会启动本类
*/
public class SystemAction extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "接收系统广播信息——短信");
//接收Intent对象当中的数据
Bundle bundle=intent.getExtras();
//在Bundle对象中有一个属性为pdus,该属性为Object数组
Object[] myOBJpdus=(Object[])bundle.get("pdus");
//创建一个SmsMessage类型的数组
SmsMessage[] messages=new SmsMessage[myOBJpdus.length];
System.out.println(messages.length);
for (int i = 0; i < myOBJpdus.length; i++) {
//使用Object数组中的对象创建SmsMessage对象
messages[i]=SmsMessage.createFromPdu((byte[])myOBJpdus[i]);
//获取到信息对象的内容
System.out.println(messages[i].getDisplayOriginatingAddress());
System.out.println(messages[i].getDisplayMessageBody());
Toast.makeText(context, "接收系统广播信息,短信内容为:"+messages[i].getDisplayOriginatingAddress()+"\n"+messages[i].getDisplayMessageBody(), 5000).show();
}
}
}
System2Action.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 上午8:17:20
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:System2Action.java
* @版权声明:www.cctvjiatao.com
* @功能: 当网络状态发生变化时,会启动本类
*/
public class System2Action extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "接收系统广播信息——网络状态发生变化");
if (!isNetworkAvailable(context)) {
Toast.makeText(context, "网络不可用!", 5000).show();
}
}
/**
* 网络是否可用,如果网络可用,再判断网络连接方式
*/
public boolean isNetworkAvailable(Context context) {
ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] info = mgr.getAllNetworkInfo();
NetworkInfo mobileInfo = mgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifiInfo = mgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo vpnInfo = mgr.getNetworkInfo(ConnectivityManager.TYPE_VPN);
NetworkInfo activeInfo = mgr.getActiveNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
Log.e(TAG, "mobile:" + mobileInfo.isConnected() + "\nwifi:" + wifiInfo.isConnected() + "\nvpn:" + vpnInfo.isConnected() + "\nactive:" + activeInfo.getTypeName());
Toast.makeText(context, "mobile:" + mobileInfo.isConnected() + "\nwifi:" + wifiInfo.isConnected() + "\nvpn:" + vpnInfo.isConnected() + "\nactive:" + activeInfo.getTypeName(), 5000).show();
return true;
}
}
}
return false;
}
}
System3Action.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午8:46:38
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:System3Action.java
* @版权声明:www.cctvjiatao.com
* @功能: 电话广播 ,例如拨号110时,最终播出86110
*/
public class System3Action extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "用户拨完号码了");
String phoneNum = getResultData();
Log.e(TAG, "用户拨打的号码是"+ phoneNum);
//给号码添加数字
String newPhoneNum = "+86" + phoneNum;
//把修改后的号码放回去
setResultData(newPhoneNum);
Log.e(TAG, "实际拨打的号码是"+ newPhoneNum);
}
}
System4Action.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:03:56
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:System4Action.java
* @版权声明:www.cctvjiatao.com
* @功能: 拦截指定号码的短信
*/
public class System4Action extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "收到短信");
// 获取短信内容
Bundle bundle = intent.getExtras();
// 返回的是一个Object数组
Object[] objects = (Object[]) bundle.get("pdus");
// 遍历数组得到短信内容
for (Object object : objects) {
// 把数组元素转换成短信对象
SmsMessage sms = SmsMessage.createFromPdu((byte[]) object);
// 获取发件人号码
String toPhone = sms.getOriginatingAddress();
// 获取短信内容
String smsContent = sms.getMessageBody();
Log.e(TAG, "发件人号码:" + toPhone + "短信内容" + smsContent);
// 判断是否是拦截的号码
if (toPhone.equals("10086")) {
// 拦截广播
abortBroadcast();
Log.e(TAG, "短信来自10086,已被拦截");
}
}
}
}
/*
* 虽然程序能走到拦截这一步,但是并没有阻止显示在短信收件箱里
* 这里,我们要注意一个优势,就是广播接收者是有优先级定义的,
* 我们只需要在清单注册根节点的intent-filter标签里定义一个:android:priority="1000"
* 官方文档规定的优先级数值在-1000到1000之间,1000最大
*/
System5Action.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:12:53
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:System5Action.java
* @版权声明:www.cctvjiatao.com
* @功能: 监听SD卡状态
*/
public class System5Action extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
//判断广播
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
Log.e(TAG, "SD卡就绪");
} else if (action.equals(Intent.ACTION_MEDIA_REMOVED)) {
Log.i(TAG, "SD卡拔出");
} else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTABLE)) {
Log.i(TAG, "SD卡卸载");
}
}
}
System6Action.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:15:02
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:System6Action.java
* @版权声明:www.cctvjiatao.com
* @功能: 流氓软件,监听到开机就启动这个软件,而且不让其退出,达到流氓的效果,需配合MainActivity中的onBackPressed()方法
*/
public class System6Action extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "开机");
//启动
Intent i = new Intent(context, MainActivity.class);
//在Activity之外启动需要设置Flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
System7Action.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:21:38
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:System7Action.java
* @版权声明:www.cctvjiatao.com
* @功能: TODO
*/
public class System7Action extends BroadcastReceiver {
private final String TAG = getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
//判断广播类型
String action = intent.getAction();
//获取包名
Uri appName = intent.getData();
if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
Log.e(TAG, "安装" + appName);
} else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
Log.e(TAG, "更新" + appName);
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
Log.e(TAG, "卸载" + appName);
}
}
}
OrderReceiverOne.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:40:04
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:OrderReceiverOne.java
* @版权声明:www.cctvjiatao.com
* @功能: 有序广播1
*/
public class OrderReceiverOne extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "One", 3000).show();
}
}
OrderReceiverTwo.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:40:04
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:OrderReceiverTwo.java
* @版权声明:www.cctvjiatao.com
* @功能: 有序广播2
*/
public class OrderReceiverTwo extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Two", 3000).show();
}
}
OrderReceiverThree.java
package com.cctvjiatao.broadcastreceiverdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* @作者: jiatao
* @修改时间:2016-4-11 下午9:40:04
* @包名:com.cctvjiatao.broadcastreceiverdemo
* @文件名:OrderReceiverThree.java
* @版权声明:www.cctvjiatao.com
* @功能: 有序广播3
*/
public class OrderReceiverThree extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Three", 3000).show();
}
}