概念引入:
廣播(Broadcast)是一種廣泛運用的在應用程序之間傳輸信息的機制,在 Android 裏面有各種各樣的廣播,比如電池的使用狀態,類似於當手機鎖屏解鎖、收到短信電話、電量過低提示,應用程序也可以接受廣播並做出程序邏輯上的處理, 去實現我們給用戶的一些提示或者其他的一些操作,這都是通過廣播監聽系統動作鎖實現的
(1)你的應用可以使用它對外部事件進行過濾,只對感興趣的外部事件(如當電話呼入時,或者數據網絡可用時)進行接收並做出響應。廣播接收器沒有用戶界面。然而,它們可以啓動一個activity或serice來響應它們收到的信息,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力,例如閃動背燈、震動、播放聲音等。一般來說是在狀態欄上放一個持久的圖標,用戶可以打開它並獲取消息。
(2)廣播接收者的註冊有兩種方法,分別是程序動態註冊和AndroidManifest文件中進行靜態註冊。
(3)動態註冊廣播接收器特點是當用來註冊的Activity關掉後,廣播也就失效了。靜態註冊無需擔憂廣播接收器是否被關閉,只要設備是開啓狀態,廣播接收器也是打開着的。
Android中的廣播接收器分爲兩種類型:標準廣播、有序廣播
標準廣播(Normal broadcasts):是一種完全異步執行的廣播,在廣播發出以後,所有的廣播接收器幾乎都會在同一時刻收到這一條廣播消息,因此它們之間沒有任何先後順序可言。這種廣播效率比較高,但通知也意味着它時無法被截斷的。
工作流程
有序廣播(Ordered broadcasts):則是一種同步執行的廣播,在廣播發出之後,同一時刻只會有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞。所以此時的廣播接收器是有先後順序的,優先級高的廣播接收器就可以先收到這條廣播,並且前面的廣播接收器還可以階段正在傳遞的廣播,這樣後面的廣播接收器就無法收到這條廣播消息了。
廣播的註冊方式:
廣播接收器的(構建)註冊廣播方式有兩種:在代碼中註冊(動態註冊)、在AndroidManifest.xml中註冊(靜態註冊)
動態註冊:廣播的接收者需要通過調用registerReceiver函數告訴系統,它對什麼樣的廣播有興趣,即指定IntentFilter,並且向系統註冊廣播接收器,即指定BroadcastReceiver:
IntentFilter counterActionFilter = new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);
registerReceiver(counterActionReceiver, counterActionFilter);
第一個參數是繼承了BroadcastReceiver的類的實例對象
第二個參數是指定想要實現的動作(廣播接收器想要監聽什麼廣播,就在第二個參數中實現相應的action就可以了)
靜態註冊:
<receiver android:name = ".接收廣播的類名">
//並且在裏面添加
<intent-filter>
<action android:name="要接收的廣播"/>
</intent-filter>
</receiver>
切記:動態註冊的廣播接收器一定都要取消註冊纔可以,可以在onDestroy()方法中通過調用unregisterReceiver()方法來實現
//解除註冊
public void onDestory(){
unregisterReceiver(counterActionReceiver);
}
廣播的發送
發送標準廣播:用sendBroadcast(intent)方法
因爲已經確定了要接收的廣播,所以一個類中需要實現廣播的發送,並且要發送的廣播爲之前所接收的廣播
發送有序廣播:有序廣播類似於中央發紅頭文件,一級一級的傳播,中間可以被截斷,截斷以後,後面的廣播接收器將收不到這條廣播
發送有序廣播和之前發送標準廣播的區別不是很大,只需要將最後sendBroadcast(intent);方法改變成sendOrderedBroadcast(intent,null);
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//標準廣播
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
//有序廣播
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent, null);
//發送本地廣播
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
###本地廣播的使用
前面所介紹的發送和接收的廣播全部是屬於系統全局廣播,即發出的廣播可以被其他任何的任何應用程序收到,並且也可以接受到來自其他應用程序的廣播。這樣容易有安全問題,所以引入本地廣播
使用本地廣播只需要在代碼中動態註冊,通過本地廣播管理器(LocalBroadcastManager)的對象調用registerReceiver()方法動態的去註冊,然後記得必須在onDestroy()方法中取消註冊
package com.example.boradcasttest;
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.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲取實例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//發送本地廣播
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
//動態註冊廣播接收器,切記要解除註冊
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
}
@Override
/*
因爲在前面通過LocalBroadcastManager對象調用registerReceiver()方法
進行了動態的註冊,所以在覆寫onDestroty()方法中需要取消註冊
*/
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
//自定義的本地廣播接收器
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "本地接收到廣播", Toast.LENGTH_SHORT).show();
}
}
}