【移動應(yīng)用開發(fā)技術(shù)】Android Day07四大組件之廣播接收者BroadcastReceiver_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Android Day07四大組件之廣播接收者BroadcastReceiver_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Android Day07四大組件之廣播接收者BroadcastReceiver_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Android Day07四大組件之廣播接收者BroadcastReceiver_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Android Day07四大組件之廣播接收者BroadcastReceiver_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費閱讀

付費下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】AndroidDay07四大組件之廣播接收者BroadcastReceiver

1.廣播和廣播接收者

Android中的廣播和廣播接收者相當于現(xiàn)實生活中的電臺和聽收音機的人,

Android系統(tǒng)內(nèi)部相當于已經(jīng)定義好了電臺,

就是內(nèi)部定義好了一些事件(外撥電話,短信到來

電池電量低sd卡狀態(tài)卸載安裝

開機啟動等等),我們開發(fā)者只需要注冊這個事件就ok了(注冊事

件就是創(chuàng)建廣播接收者之后在清單里配置意圖過濾器的action屬性,相當于聽收音機的人調(diào)頻一樣)

更確切的說,廣播接收者就是Android系統(tǒng)的全局監(jiān)聽者,可以監(jiān)聽系統(tǒng)的很多事件,只要廣播

接收者注冊了這些事件,就會被這些事件觸發(fā)。

★廣播接收者被觸發(fā),底層原理應(yīng)該是廣播事件會利用隱式意圖啟動符合條件的廣播接收者.

2.注冊廣播接收者

注冊廣播接收者有2種方式,而且一個廣播接收者配置多個過濾動作Action。

★第1種:在清單里注冊

在配置文件中注冊的接收者的特點是即使應(yīng)用程序已被關(guān)閉,該接收者依然可接受它感興趣的廣播。

上面紅色特性,已經(jīng)驗證過,確實如此!

一般大多數(shù)的廣播接收者都是在清單文件中注冊,只有少量的廣播接收者是在代碼里注冊

當然可以在清單里注冊的廣播接收者,也一定能夠在代碼里注冊。

★第2種:在Activity里注冊

在Activity中綁定接收者必須依附該應(yīng)用程序存在,或者一個BroadcastReceiver用于更新UI,就沒有必要在

程序關(guān)閉時接收者還運行,故無需在AndroidManifest.xml中注冊而可以放在Activity中注冊。

操作特別頻繁的廣播事件

比如鎖屏和解鎖這種廣播接收者在清單文件里面注冊是無效的

必需在代碼里注冊,否則會報下面這個異常。

MainActivityhasleakedIntentReceiver

ScreenReceiver@b65bb500thatwasoriginallyregisteredhere.Areyoumissinga

calltounregisterReceiver()?

代碼里注冊廣播接收者

首先,定義一個類繼承BroadcastReceiver:

publicclassScreenReceiverextendsBroadcastReceiver

下一步,在一個Activity中注冊上面定義的廣播接收者

ScreenReceiver

screenReceiver

=

new

ScreenReceiver();

//創(chuàng)建意圖對象過濾器

IntentFilter

intentFilter

=

new

IntentFilter();

intentFilter.addAction("ent.action.SCREEN_OFF");

intentFilter.addAction("ent.action.SCREEN_ON");

//注冊鎖屏和解鎖廣播

registerReceiver(screenReceiver,

intentFilter);

3.廣播接收者開發(fā)步驟

第1步:定義一個類繼承廣播接收者,并在清單或代碼里注冊,包括receiver的name屬性、

過濾器的Action屬性。

第2步:復寫定義的廣播接收者類的onReceive方法,定義廣播接收者被觸發(fā)后想實現(xiàn)的邏輯。

一般如果廣播接收者注冊了多個事件,還得先判斷一下事件的類型。

public

void

onReceive(Context

context,

Intent

intent)

{

//得到事件的類型

String

action

=

intent.getAction();

}案例:注意不同的案例獲取數(shù)據(jù)的方式4.案例1_IP撥號器(外撥電話)

■清單配置

<receiver

android:name="com.itheima.ipdialerListener.OutGoingReceiver"

>

<intent-filter>

<!--

配置action

new

outgoing

call

-->

<action

android:name="ent.action.NEW_OUTGOING_CALL"/>

</intent-filter>

</receiver>

■權(quán)限

<uses-permission

android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

■廣播接收者的接收后的邏輯

public

class

OutGoingReceiver

extends

BroadcastReceiver

{

@Override

public

void

onReceive(Context

context,

Intent

intent)

{

//獲取廣播事件的數(shù)據(jù)-電話號碼

String

phoneNumber

=

getResultData();

//直接調(diào)用BroadcastReceiver的方法

System.out.println("phoneNumber:"

+

phoneNumber);

//假如電話號碼開頭是0,就是長途。

if(phoneNumber.startsWith("0"))

{

phoneNumber

=

"95128"

+

phoneNumber;

}

//改變廣播當前的數(shù)據(jù)-用修改過后電話號碼替換。

setResultData(phoneNumber);

//注意這個方法只能與有序廣播聯(lián)用

}

}

將應(yīng)用程序安裝好,撥打一個手機號以0開始的電話號碼0123,點擊撥打按鈕,效果如下所示:

5.案例2_sd卡狀態(tài)監(jiān)聽

■清單配置

注意過濾器里多了一個<dataandroid:scheme="file"/>

<receiver

android:name="com.itheima.sdcard.SDCardReceiver"

>

<intent-filter>

<action

android:name="ent.action.MEDIA_MOUNTED"/>

<action

android:name="ent.action.MEDIA_UNMOUNTED"/>

<data

android:scheme="file"/>

</intent-filter>

</receiver>

■權(quán)限

■廣播接收者的接收后的邏輯

public

class

SDCardReceiver

extends

BroadcastReceiver

{

@Override

public

void

onReceive(Context

context,

Intent

intent)

{

//因為清單里有2個action,所以要獲取action的類型。

String

action

=

intent.getAction();

if(Intent.ACTION_MEDIA_MOUNTED.equals(action))

{

System.out.println("sd卡掛載了");

}else

if(Intent.ACTION_MEDIA_UNMOUNTED.equals(action)){

System.out.println("sd卡卸載了");

}else

{

System.out.println("sd監(jiān)聽出錯了");

}

}

}

進入2.3這些低版本的模擬器,settings-storage里面可以模擬sd的掛載與卸載。

6.案例3_短信監(jiān)聽器

短信監(jiān)聽的底層原理,應(yīng)該是短信數(shù)據(jù)庫內(nèi)容提供者者安插了內(nèi)容觀察者,一旦手機接收到短

信,勢必短信數(shù)據(jù)庫會發(fā)生變化,內(nèi)容觀察者分析到了就會發(fā)送一條短信接收的廣播,并且把短

信相關(guān)的信息封裝在了意圖對象里。

■清單配置

高版本的ADT提示里沒有action對應(yīng)的選項,應(yīng)從低版本ADT拷貝action值到清單中。

<receiver

android:name="com.itheima.msglistener.MsgListener"

>

<intent-filter>

<action

android:name="vider.Telephony.SMS_RECEIVED"/>

</intent-filter>

</receiver>

■權(quán)限

<uses-permission

android:name="android.permission.RECEIVE_SMS"/>

■廣播接收者的接收后的邏輯

注意SmsMessage對象所在的包

//獲取短信數(shù)據(jù),可能有多條短信數(shù)據(jù)吧。

//由此可見,短信的數(shù)據(jù)在intent里的封裝的格式是Bundle,也就是map集合。

Object[]

object

=

(Object[])

intent.getExtras().get("pdus");

//創(chuàng)建SmsMessage對象來分離短信的各項內(nèi)容

,注意SmsMessage所在的包。

for

(Object

obj

:

object)

{

//創(chuàng)建SmsMessage實例,解析短信信息:發(fā)送者、短信內(nèi)容

SmsMessage

smsMessage

=

SmsMessage.createFromPdu((byte[])

obj);

String

messageBody

=

smsMessage.getMessageBody();

String

originatingAddress

=

smsMessage.getOriginatingAddress();

System.out.println("短信發(fā)送者:"

+

originatingAddress);

System.out.println("短信內(nèi)容:"

+

messageBody);

}

關(guān)于短信監(jiān)聽,android2.3版本時沒有考慮到安全問題,4.0之后,考慮到安全問題,廣播接

收者需要有一個啟動界面才能生效(但不一定要求界面就要啟動,也就是說只要有個activity就行了

)。

對于用戶來說,在2.3這些低版本設(shè)備上,對于沒有界面的短信監(jiān)聽應(yīng)用,如果一旦有短信發(fā)送過

來,應(yīng)用就會被激活,在setting中的forcestop按鈕也才會變得可選,可以在setting中點擊這個按

鈕就能關(guān)閉應(yīng)用

對于流氓程序員來說,不但可以做個沒有啟動界面和圖標的應(yīng)用,更可以結(jié)合卸載監(jiān)聽事件,不讓

安裝的流氓應(yīng)用卸載,還可以加個密碼確認之后才能輸入,要多流氓就有多流氓。

7.案例4_應(yīng)用安裝與卸載的監(jiān)聽

■清單配置

注意過濾器多了一個<dataandroid:scheme="package"/>

<receiver

android:name="com.itheima.packageaddandremove.PackageReceiver"

>

<intent-filter>

<action

android:name="ent.action.PACKAGE_ADDED"

/>

<action

android:name="ent.action.PACKAGE_REMOVED"

/>

<data

android:scheme="package"

/>

</intent-filter>

</receiver>

■權(quán)限

■廣播接收者的接收后的邏輯

//得到包名

Uri

packageName

=

intent.getData();

//獲取事件類型

String

action

=

intent.getAction();

if("ent.action.PACKAGE_ADDED".equals(action))

{

System.out.println(packageName

+

"安裝了。。。。。");

}

else

if("ent.action.PACKAGE_REMOVED".equals(action))

{

System.out.println(packageName

+

"卸載了。。。。。");

}

8.案例5_開機啟動監(jiān)聽

如果想在廣播接收者里啟動activity,必須要為意圖指定一個任務(wù)棧標記。

■清單配置

■權(quán)限

■廣播接收者的接收后的邏輯

開機啟動廣播監(jiān)聽,可以與很多地方相結(jié)合。如啟動activity或service,可以在service里又與

其它的監(jiān)聽事件如短信、電話監(jiān)聽相結(jié)合,做出電話竊聽器這樣子之類的應(yīng)用。

另外,開機啟動監(jiān)聽比較的費時,有時候其實是實現(xiàn)了,但是Log就是不出信息,可以采用開

啟Activity的方式(記得intent要setFlags),這樣效果就明顯了。9.電源鍵長按廣播

定義廣播類:package

com.done.assistcarrecord.receiver;

import

android.content.BroadcastReceiver;

import

android.content.Context;

import

android.content.Intent;

import

android.util.Log;

import

com.done.assistcarrecord.MyApplication;

import

mon.Constants;

import

com.done.assistcarrecord.util.ShellUtil;

import

com.done.assistcarrecord.util.log.ExceptionLogCatcher;

/**

*

Created

by

Administrator

on

2018/4/15

0015.

*

監(jiān)聽電源長按,防止模擬點擊事件時誤操作點擊了飛行模式。

*/

public

class

PowerBroadcastReceiver

extends

BroadcastReceiver

{

private

static

final

String

TAG

=

"PowerBroadcastReceiver";

public

static

boolean

isPowerDialogShowed

=

false;

//是否出現(xiàn)電源長按界面

@Override

public

void

onReceive(Context

context,

Intent

intent)

{

//你自己先把

reasons

==

homekey

長按homekey

排除,剩下的做下面的處理

String

reason

=

intent.getStringExtra("reason");

if

(intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)){

System.out.println("Intent.ACTION_CLOSE_SYSTEM_DIALOGS

:

"

+

intent.getStringExtra("reason"));

if

(intent.getExtras()!=null

&&

intent.getExtras().getBoolean("myReason")){

}else

if

(reason

!=

null){

if

(reason.equalsIgnoreCase("globalactions")){

//監(jiān)聽電源長按鍵的方法:

Intent

myIntent

=

new

Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);

myIntent.putExtra("myReason",

true);

context.sendOrderedBroadcast(myIntent,

null);

Log.e(TAG,

"onReceive:

電源

鍵被長按");

ExceptionLogCatcher.getInstance().put("電源

鍵被長按");

isPowerDialogShowed

=

true;

MyApplication.gHANDLER.postDelayed(new

Runnable()

{

@Override

public

void

run()

{

ShellUtil.execCommand(Constants.CLICK_CANCEL_POWER_LONG_PRESS_DIALOG,

true);

}

},500);

isPowerDialogShowed

=

false;

ExceptionLogCatcher.getInstance().put("模擬關(guān)閉電源對話框成功");

}else

if

(reason.equalsIgnoreCase("homekey")){

//<span

>監(jiān)聽</span><span

>Home鍵的方法</span>

//在這里做一些你自己想要的操作,比如重新打開自己的鎖屏程序界面,這樣子就不會消失了

Log.e(TAG,

"onReceive:

Home

鍵被觸發(fā)");

}else

if

(reason.equalsIgnoreCase("recentapps")){

//監(jiān)聽Home鍵長按的方法

Log.e(TAG,

"onReceive:

Home

鍵被長按");

}

}

}

}

}

在代碼里注冊(好像在清單里注冊,是接收不到廣播的)@Override

public

void

onCreate()

{

//監(jiān)聽長按事件

final

IntentFilter

homeFilter

=

new

IntentFilter(

Intent.ACTION_CLOSE_SYSTEM_DIALOGS);

powerBroadcastReceiver

=

new

PowerBroadcastReceiver();

registerReceiver(powerBroadcastReceiver,

homeFilter);

一般在onDestroy方法里注銷廣播if(powerBroadcastReceiver

!=

null){

unregisterReceiver(powerBroadcastReceiver);

powerBroadcastReceiver

=

null;

}

10.TIME_TICK廣播

/mrleeapple/article/details/50525236

(系統(tǒng)源碼明確指出不能靜態(tài)注冊)####################################################################################上面講到幾個案例,都有一個共同的特點:廣播都是由系統(tǒng)發(fā)送的。那么可以自己定義并發(fā)送廣播嗎?查看API會發(fā)現(xiàn)Context類有發(fā)送廣播的方法,Activity和Service都繼承了Context,所以這兩個對象都可以發(fā)送廣播,或者只要有Context對象的對象都可以發(fā)送廣播。廣播就是在發(fā)送Intent,Intent用來封裝數(shù)據(jù)并且過濾廣播接收者,發(fā)送廣播有2種方式:(系統(tǒng)發(fā)送廣播也是用的這2個方法)1.發(fā)送無序廣播

■發(fā)送廣播代碼:sendBroadcast

public

void

sendUnOrder(String

content)

{

Intent

intent

=

new

Intent();

//注意設(shè)置意圖對象的action,以便過濾發(fā)送給哪個廣播接收者。

intent.setAction("com.itheima.UNORDER_SEND");

intent.putExtra("content",

content);

//無序廣播的發(fā)送方法

sendBroadcast(intent);

}

■廣播接收者清單配置:

只要定義一個廣播接收者,在清單里配置它的action屬性和發(fā)送代碼里的action參數(shù)一樣,發(fā)送廣

播的方法就會將意圖Intent發(fā)送給符合條件的廣播接收者的onReceive參數(shù)里,這也印證了為什么廣播

接收者的接收方法里會有一個Intent參數(shù)的原因:onReceive參數(shù)里的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論