1、廣播接收者
- BroadcastReceiver
- 接收系統發出的廣播
- 現實中的廣播:電臺為了傳達一些消息,而發送的廣播,通過廣播攜帶要傳達的消息,群眾只要買一個收音機,就可以收到廣播了
- ?Android中的廣播:系統在運行過程中,會發生很多事件,系統為了讓其他應用知道系統發生了這個事件,會發送一個對應該事件的廣播,比如:電量改變、收到短信、撥打電話、屏幕解鎖、系統開機,應用只要注冊一個廣播接收者,就可以接收到系統發出的廣播
2、定義方式
- 定義一個類繼承BroadcastReceiver
-
package com.ecollab.ipdialor;import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;public class CallReceiver extends BroadcastReceiver {//收到廣播時調用 @Overridepublic void onReceive(Context context, Intent intent) {//取出廣播中的號碼String number = getResultData();String newNumber = "17951" + number;//把修改后的號碼放入廣播中 setResultData(newNumber);} }
- 在清單文件中配置該類,指定接收的廣播種類?
<receiver android:name="com.ecollab.ipdialer.CallReceiver">
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
-
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.ecollab.ipdialor"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="14"android:targetSdkVersion="21" /><uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid: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.ecollab.ipdialor.CallReceiver"><intent-filter><action android:name="android.intent.action.NEW_OUTGOING_CALL" /></intent-filter></receiver></application></manifest>
- 廣播是通過intent發送的,intent中會攜帶一個action,系統會在所有清單文件中尋找,看哪一個廣播接收者的intent-filter和廣播中的intent是匹配的,那么這個廣播接收者就會收到這條廣播
3、IP撥號器
- 系統撥打號碼時,會發出一個廣播,廣播中會攜帶撥打的號碼,注冊廣播接收者接收這個廣播,取出這個號碼,修改這個號碼,然后把修改后的號碼重新放入廣播
- 廣播接收者所在進程即便沒有啟動,廣播發送出來時,系統也會啟動這個進程,然后把廣播交給廣播接收者
- 接收打電話廣播需要權限?<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
4、短信攔截器
- 系統收到短信時會產生一條廣播,廣播中包含了短信的號碼和內容
- 設置廣播接收者的優先級,大于系統短信應用,先一步收到短信廣播,然后攔截廣播,短信應用收不到廣播,用戶就看不到短信了
-
定義廣播接收者接收短信廣播(所有系統廣播里怎么發數據我們自己建的應用就怎么取數據)
public void onReceive(Context context, Intent intent) {
//拿到系統廣播里攜帶的短信內容
Bundle bundle = intent.getExtras();
Object[] objects = (Object[]) bundle.get("pdus");
for(Object ob : objects ){
//通過object對象創建一個短信對象
SmsMessage sms = SmsMessage.createFromPdu((byte[])ob);
?
if("13888".equals(sms.getOriginatingAddress()))
{
abortBroadcast();//攔截短信
}
System.out.println(sms.getMessageBody());
System.out.println(sms.getOriginatingAddress());
}
}
- 系統創建廣播時,把短信存放到一個數組,然后把數據以pdus為key存入bundle,再把bundle存入intent。攔截后的短信再發給系統短信應用。
- 清單文件中配置廣播接收者接收的廣播類型,注意要設置優先級屬性(-1000至1000),要保證優先級高于短信應用,才可以實現攔截
<receiver android:name="com.itheima.smslistener.SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
- 添加權限?<uses-permission android:name="android.permission.RECEIVE_SMS"/>
- 4.0之后,進程需要啟動過一次,廣播接收者才能生效
- 4.0之后,用戶手動停止進程,那么廣播接收者再也不會啟動了,直到用戶下一次手動啟動進程
?5、監聽SD卡狀態
- 清單文件中定義廣播接收者接收的類型,監聽SD卡常見的三種狀態,所以廣播接收者需要接收三種廣播
<receiver android:name="com.itheima.sdcradlistener.SDCardReceiver">
<intent-filter >
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<action android:name="android.intent.action.MEDIA_REMOVED"/>
<data android:scheme="file"/>
</intent-filter>
</receiver>
- 廣播接收者的定義(不用switch對比字符串)
public class SDCardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 區分接收到的是哪個廣播
String action = intent.getAction();
if(action.equals("android.intent.action.MEDIA_MOUNTED")){
System.out.println("sd卡就緒");
}
else if(action.equals("android.intent.action.MEDIA_UNMOUNTED")){
System.out.println("sd卡被移除");
}
else if(action.equals("android.intent.action.MEDIA_REMOVED")){
System.out.println("sd卡被拔出");
}
}
}
6、勒索軟件(流氓軟件)
?接收開機廣播,在廣播接收者中啟動勒索的Activity(開機啟動)
- 清單文件中配置接收開機廣播
<receiver android:name="com.itheima.lesuo.BootReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
- 權限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
- 定義廣播接收者
@Override
public void onReceive(Context context, Intent intent) {
//開機的時候就啟動勒索軟件
Intent it = new Intent(context, MainActivity.class);
//it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(it);
}
- 以上代碼還不能啟動MainActivity,因為廣播接收者的啟動,并不會創建任務棧,那么沒有任務棧,就無法啟動activity
- 手動設置創建新任務棧的flag。?it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7、監聽應用的安裝、卸載、更新
應用在安裝卸載更新時,系統會發送廣播,廣播里會攜帶應用的包名
- 清單文件定義廣播接收者接收的類型,因為要監聽應用的三個動作,所以需要接收三種廣播
<receiver android:name="com.itheima.app.AppReceiver">
<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>
- 廣播接收者的定義
public void onReceive(Context context, Intent intent) {
//區分接收到的是哪種廣播
String action = intent.getAction();
//獲取廣播中包含的應用包名
Uri uri = intent.getData();
if(action.equals("android.intent.action.PACKAGE_ADDED")){
System.out.println(uri + "被安裝了");
}
else if(action.equals("android.intent.action.PACKAGE_REPLACED")){
System.out.println(uri + "被更新了");
}
else if(action.equals("android.intent.action.PACKAGE_REMOVED")){
System.out.println(uri + "被卸載了");
}
}
8、發送自定義廣播
Intent intent = new Intent();
intent.setAction("ecollab.ui.web");
sendBroadcast(intent);
接收跟系統廣播相同。
9、廣播的兩種類型
- 無序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,并且是沒有先后順序(同時收到)
- 有序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,但是會按照廣播接收者的優先級來決定接收的先后順序:發送方法為sendOrderedBroadcast
- 優先級的定義:-1000~1000
- 結果接收者:所有廣播接收者都接收到廣播之后,它才接收,并且一定會接收
//resultReceiver在所有廣播接收者收到廣播后,才會收到。(定義內部接收者類,無需在清單文件中注冊)
sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras)
?
class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
}
}
sendOrderedBroadcast(intent, null, new?MyReceiver(),null,0,"廣播內容",null);
?
- abortBroadCast:阻止其他接收者接收這條廣播,類似攔截,只有有序廣播可以被攔截
?