15、四大组件--BroadcastReceiver
一、廣播
廣播接受者用來接收廣播Intent的。廣播Intent的發送是通過調用sendBroadcast/sendOrderedBroadcasr來實現的。通常一個廣播Intent可以被訂閱次Intent的多個廣播接受者所接收。
1.1、廣播特點
2.3:第一次安裝不管有沒有頁面或在設置頁面強行停止,廣播接受者都生效。
4.0:安全升級后,廣播接受者第一次安裝必須有界面,設置頁面如果強行停止,廣播不再生效。
廣播中開啟activity:
Intent intent=new Intent(context,main.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent);1.3、生命周期
廣播生命周期只有十秒左右,如果在onReceive()內做超過十秒內的事情,就會報錯。
每次廣播到來時,會重新創建 BroadcastReceiver對象,并且調用 onReceive()方法,執行完以后,該對象即被銷毀.當onReceive()方法在10 秒內沒有執行完畢
,Android會認為該程序無響應.所以在BroadcastReceiver里不能做一些比較耗時的操作,否側會彈出ANR(Application No Response)的對話框。
1.4、自定義廣播
1.無序廣播
a) 無序廣播不可以被攔截,如果被攔截則報錯
b) 所有接受無序廣播的廣播接收者在此廣播發送時均能接受到此廣播。
c) 無序廣播是通過sendBroadcast方法進行發送。
// 創建意圖 Intent intent = new Intent(); // 設置Action intent.setAction("cn.legend.broadcast"); // 綁定數據 intent.putExtra("data","我是無序廣播數據"); // 發送無序廣播 sendBroadcast(intent);2.有序廣播
a)有序廣播可以被攔截,且優先級高的接受者可以攔截優先級低的。
b)廣播接收者的優先級取值范圍:-1000(最低)--1000(最高)。
c)相同優先級下,接收的順序要看清單文件聲明順序,誰先聲明誰先收到廣播。
d)無序廣播使用sendOrderedBroadcasr方法發送,使用abortBroadcast方法攔截。
e)廣播接收者的優先級在清單文件中聲明:<intent-filter>標簽下設置"android:property"屬性設置。
Intent intent = new Intent(); intent.setAction("cn.legend.data"); /*** 參數1:意圖,廣播,所有匹配的這一意圖將接收機接收廣播。* 參數2:receiverPermission 這是權限,一個接收器必須持以接收您的廣播。如果為 null,不經許可的要求。 * 參數3:BroadcastReceiver類型,自己定義的接收器作為最終接收器* 參數4:Handle類型,用于執行接收器的回調,如果為null則在主線程中執行* 參數5:initialCode 一種結果代碼的初始值。通常為 Activity.RESULT_OK 。這個值是 -1 ;* 參數6:initialData 一種結果數據的初始值。通常情況下為空 , 是 String 類型 ;* 參數7:Bundle類型,額外的數據*/ sendOrderedBroadcast(intent,null,null,null,RESULT_OK,"一萬元",null);3.粘性廣播
Intent會一直保留到廣播事件結束,而這種廣播也沒有所謂的10秒限制。在發送完廣播后才被注冊的廣播接收者無法接收到在注冊前發送的廣播,但是可以接收到注冊前發送的sticky broadcast(粘性廣播)。
Intent intent = new Intent(); intent.setAction("cn.legend.data"); sendStickyBroadcast(intent);下面看一個粘性廣播的實例:
需求:發送一個粘性廣播,并在5秒后開啟一個Activity,在新開啟的Activity中注冊廣播接受者來接收到廣播。
a) 發送一個粘性廣播,5秒后打開SecondActivity:
public class MainActivity extends Activity {private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {Intent intent = new Intent(MainActivity.this, SecondActivity.class);startActivity(intent);};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sendStickBroadcastMethod();// 五秒后開啟ActivityMessage startMessage = Message.obtain();mHandler.sendMessageDelayed(startMessage, 5 * 1000);}/*** 發送粘性廣播的方法*/private void sendStickBroadcastMethod() {Intent intent = new Intent();intent.setAction("cn.legend.stick");intent.putExtra("time", String.valueOf(System.currentTimeMillis()));sendStickyBroadcast(intent);} }b) SecondActivity中注冊廣播接受者來接收到廣播:
public class SecondActivity extends Activity {private MyBroadCastReceiver mReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);mReceiver = new MyBroadCastReceiver();IntentFilter intentFilter=new IntentFilter();intentFilter.addAction("cn.legend.stick");registerReceiver(mReceiver, intentFilter);}/*** 廣播接受者*/private class MyBroadCastReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {String time = intent.getStringExtra("time");System.out.println("收到發送的時間:" + time);System.out.println("當前的系統時間:" + System.currentTimeMillis());}}@Overrideprotected void onDestroy() {super.onDestroy();if(mReceiver != null){unregisterReceiver(mReceiver);}} }c) 最后不要忘記在AndroidManifest.xml中添加權限:
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
4.本地廣播
前面所介紹的廣播都屬于系統全局廣播,廣播可以被任何應用所接收到,這樣就導致安全問題。本地廣播只能在應用程序的內部進行傳遞,更加安全和高效。
public class MainActivity extends Activity {private LocalBroadcastManager mManager;private LocalRecerver mLocalRecerver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn = (Button) findViewById(R.id.btn);mManager = LocalBroadcastManager.getInstance(this);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 發送本地廣播Intent intent = new Intent("cn.legend.local.LOCAL_BROADCAST");mManager.sendBroadcast(intent);}});// 注冊廣播監聽器IntentFilter filter = new IntentFilter();filter.addAction("cn.legend.local.LOCAL_BROADCAST");mLocalRecerver = new LocalRecerver();mManager.registerReceiver(mLocalRecerver, filter);}// 注冊本地廣播接收器class LocalRecerver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show(); }} }注意:本地廣播只能采用動態注冊,因為靜態注冊主要是為了讓程序在未啟動的情況下也能收到廣播,而發送本地廣播時我們的程序已經啟動了。
1.5、廣播注冊
1.靜態注冊
靜態注冊是直接在清單文件中進行配置
<receiver android:name="cn.legend.regist.ScreenReceiver"><intent-filter ><action android:name="android.intent.action.SCREEN_OFF"/><action android:name="android.intent.action.SCREEN_ON"/></intent-filter> </receiver>2.動態注冊
在Activity中進行動態注冊時,在Activity銷毀的時候一定要取消注冊,否則會內存泄露。
public class MainActivity extends Activity {private ScreenReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//創建自定義的廣播接收對象的實例receiver = new ScreenReceiver();//創建過濾器的類IntentFilter filter = new IntentFilter();filter.addAction("android.intent.action.SCREEN_OFF");filter.addAction("android.intent.action.SCREEN_ON");//動態注冊 registerReceiver(receiver, filter);}@Overrideprotected void onDestroy() {//取消注冊 unregisterReceiver(receiver);super.onDestroy();} }1.6、系統廣播
1.監聽SD卡
a) 創建一個SdcardStateReceiver的類繼承BroadcastReceiver,創建廣播需要在清單文件中先進行注冊,而監測SD卡還需要配置action和data屬性
<receiver android:name="cn.legend.listensdcard.SdcardStateReceiver" ><!-- 指定內存卡被掛載和卸載的動作 --><intent-filter><action android:name="android.intent.action.MEDIA_MOUNTED" /><action android:name="android.intent.action.MEDIA_UNMOUNTED" /><data android:scheme="file" /></intent-filter> </receiver>b) 在SdcardStateReceiver類中寫下如下代碼:
public class SdcardStateReceiver extends BroadcastReceiver {//接受注冊廣播的時候調用 @Overridepublic void onReceive(Context context, Intent intent) {//獲取廣播的事件String action = intent.getAction();//判斷獲取到的事件if("android.intent.action.MEDIA_MOUNTED".equals(action)){//彈出土司提示Toast.makeText(context, "Sd卡被掛載的了....", 0).show();}else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){Toast.makeText(context, "Sd卡被卸載的了....", 0).show();}} }2.監聽來電
a) 在MainActivity中獲取安全中心的號碼,保存到配置文件中:
String phone = et_phone.getText().toString().trim(); if(TextUtils.isEmpty(phone)){Toast.makeText(this, "號碼不能為空", 0).show();return; } sp.edit().putString("phone", phone).commit(); Toast.makeText(getApplicationContext(), "保存成功", 0).show();b) 創建廣播類OutGoingCallReceiver,在清單文件中聲明:
<receiver android:name="cn.legend.caller.OutGoingCallReceiver"><intent-filter ><action android:name="android.intent.action.NEW_OUTGOING_CALL"/></intent-filter> </receiver>c) 在OutGoingCallReceiver中拼接安全號+電話號碼,當撥打電話是0開頭的長途電話,則添加安全中心號碼:
public class OutGoingCallReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//監聽獲取當前撥打的電話String phone = getResultData();//從配置文件取出要拼接的區號SharedPreferences sp = context.getSharedPreferences("config", 0);String number = sp.getString("phone", "");//判斷號碼是否以0開頭,如果是則說明是長途,就帶上區號if(phone.startsWith("0")){setResultData(number+phone);}} }注:需要在清單文件中添加權限:android.permission.PROCESS_OUTGOING_CALLS
3.監聽短信
a) 創建一個廣播類SmsReceiver用來監聽和攔截短信:
public class SmsReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//通過短信獲取信息,返回值需要手動改成Object[]數組Object[] objects = (Object[]) intent.getExtras().get("pdus");for (Object object : objects) {SmsMessage message = SmsMessage.createFromPdu((byte[])object);String body = message.getMessageBody();String address = message.getOriginatingAddress();System.out.println("bdoy:"+body+",address:"+address);}} }b) 清單文件配置:
<receiver android:name="cn.legend.sms.SmsReceiver" ><intent-filter><action android:name="android.provider.Telephony.SMS_RECEIVED" /></intent-filter> </receiver>注:攔截短信需要在清單文件配置權限:android.permission.RECEIVE_SMS
4.監聽安裝
a) 創建廣播類AppStateReceiver,在清單文件中配置,不需要配置權限:
<receiver android:name="cn.legend.listen.AppStateReceiver" ><intent-filter><!-- 監聽程序安裝和卸載 --><action android:name="android.intent.action.PACKAGE_ADDED" /><action android:name="android.intent.action.PACKAGE_REMOVED" /><data android:scheme="package" /></intent-filter> </receiver>b) 在AppStateReceiver中寫下如下代碼進行監聽
public class AppStateReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();//判斷是安裝還是卸載if("android.intent.action.PACKAGE_ADDED".equals(action)){System.out.println("應用程序被安裝了...");}else if("android.intent.action.PACKAGE_REMOVED".equals(action)) {System.out.println("應用程序被卸載了...");}} }5.監聽開機
a) 創建廣播類BootReceiver,清單文件做如下配置,不需要權限:
<receiver android:name="cn.legend.reboot.BootReceiver" ><intent-filter><!-- 開機自動啟動 --><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter> </receiver>b) 在BootReceiver中使用廣播開啟activity
public class BootReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {System.out.println("手機已經啟動");//在廣播中開啟一個activity Intent intent2 = new Intent(context, MainActivity.class); //由任務棧來開啟 intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent2); } }##############################################
轉載于:https://www.cnblogs.com/pengjingya/p/5508742.html
總結
以上是生活随笔為你收集整理的15、四大组件--BroadcastReceiver的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 恋与制作人白夜配音
- 下一篇: SAP管理员SAP*和DDIC被锁定后如