安卓的廣播機制:
說明:廣播廣播,其實就是一個地方將信息傳播出去,只要有廣播接收器的地方都能同時接收到信息。安卓的廣播機制一般可以針對應用內的廣播,也可以針對跨應用廣播。例如電池的事件,電池快沒電的時候,會發送一個廣播,如果你的應用中有接收這個廣播,則就會調用廣播接收的程序。
廣播和Service都是在UI線程中處理的,所以使用廣播的時候,不能處理延遲很長的操作,否則會阻礙UI線程的更新。通過廣播,可以監聽外部APP發送過來的廣播消息,通過這些廣播消息,可以做出相應的處理。
看一個圖:
一些觀點:
- 在Android 中如果要發送一個廣播必須使用sendBroadCast 向系統發送對其感興趣的廣播接收器中。
- 使用廣播必須要有一個intent 對象必設置其action動作對象。
- 使用廣播必須在配置文件中顯式的指明該廣播對象
- 每次接收廣播都會重新生成一個接收廣播的對象
- 在BroadCast 中儘量不要處理太多邏輯問題,建議複雜的邏輯交給Activity 或者 Service 去處理
廣播例子,常駐型廣播
常駐型廣播,當你的應用程序關閉了,如果有廣播信息來,你寫的廣播接收器同樣的能接受到,他的註冊方式就是在你的應用程序中的AndroidManifast.xml進行註冊。
首先需要配置AndroidMainfest.xml
- <!--
- android:name就是限定了只能在 TestReceiver
- 廣播接收器中接收 android.intent.action.EDIT類型的廣播
- -->
- <receiver android:name=".TestReceiver" >
- <intent-filter>
- <action android:name="android.intent.action.EDIT" />
- </intent-filter>
- </receiver>
- <receiver android:name=".Test2Receiver" >
- <intent-filter>
- <action android:name="android.intent.action.EDIT" />
- </intent-filter>
- </receiver>
發送一個廣播 MainActivity.java:
- package com.example.test.com;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.widget.Button;
- @SuppressLint("HandlerLeak")
- public class MainActivity extends Activity {
- private Button btn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- btn = (Button) findViewById(R.id.button1);
- //圖片點擊的時候
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();//採用intent發送數據
- intent.setAction(Intent.ACTION_EDIT);//只發送給action爲ACTION_EDIT的對象
- Bundle bundle = new Bundle();
- bundle.putString("val", "Hello World");
- intent.putExtras(bundle);
- //通過廣播方式發送該intent,只有特定action的接收者才能收到該廣播信息
- MainActivity.this.sendBroadcast(intent);
- }
- });
- }
- }
接收廣播,需要繼承BroadcastReceiver類,並且實現onReceive方法:
TestReceiver:
- package com.example.test.com;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- public class TestReceiver extends BroadcastReceiver {
- public TestReceiver() {
- System.out.println("TestReceiver");
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- //這邊可以獲取Action的名稱
- if (action.equals(Intent.ACTION_EDIT)) {
- Bundle bundle = intent.getExtras();
- System.out.println("OnReceiver" + bundle.getString("val"));
- }
- }
- }
Test2Receiver:
- package com.example.test.com;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- public class Test2Receiver extends BroadcastReceiver {
- public Test2Receiver() {
- System.out.println("Test2Receiver");
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_EDIT)) {
- Bundle bundle = intent.getExtras();
- System.out.println("OnReceiver2" + bundle.getString("val"));
- }
- }
- }
點擊按鈕後,控制檯效果:
接收器的生命週期:
廣播例子,非常駐型廣播
當應用程序結束了,廣播自然就沒有了,比如你在activity中的onCreate或者onResume中註冊廣播接收器在onDestory中卸載廣播接收器。這樣你的廣播接收器就一個非常駐型的了。這種也叫動態註冊。
- package com.example.test.com;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.widget.Button;
- @SuppressLint("HandlerLeak")
- public class MainActivity extends Activity {
- private Button btn;
- private TestReceiver testReceiver;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- //初始化的時候註冊
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_EDIT);
- testReceiver = new TestReceiver();
- registerReceiver(testReceiver, filter);
- btn = (Button) findViewById(R.id.button1);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();//採用intent發送數據
- intent.setAction(Intent.ACTION_EDIT);//只發送給action爲ACTION_EDIT的對象
- Bundle bundle = new Bundle();
- bundle.putString("val", "Hello World");
- intent.putExtras(bundle);
- //通過廣播方式發送該intent,只有特定action的接收者才能收到該廣播信息
- MainActivity.this.sendBroadcast(intent);
- }
- });
- }
- @Override
- protected void onDestroy() {
- unregisterReceiver(testReceiver);
- }
- }
- package com.example.test.com;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- public class TestReceiver extends BroadcastReceiver {
- public TestReceiver() {
- System.out.println("TestReceiver");
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- //這邊可以獲取Action的名稱
- if (action.equals(Intent.ACTION_EDIT)) {
- Bundle bundle = intent.getExtras();
- System.out.println("OnReceiver" + bundle.getString("val"));
- }
- }
- }
下面是一個內部類實現廣播接收的例子,通過內部類實現,可以動態監聽廣播消息,並且對廣播進行UI界面上的處理
- package com.example.test.com;
- 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.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- private ButtonOnClickListener btnListener;
- private Button btn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.main);
- btn = (Button) findViewById(R.id.button1);
- btnListener = new ButtonOnClickListener();
- btn.setOnClickListener(btnListener);
- }
- class ButtonOnClickListener implements OnClickListener {
- @Override
- public void onClick(View v) {
- Toast.makeText(getBaseContext(), "YES!", Toast.LENGTH_SHORT).show();
- TestBroadcast testBroadCast = new TestBroadcast();
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_EDIT); //只有持有相同的action的接受者才能接收此廣播
- registerReceiver(testBroadCast, filter); //註冊
- Intent intent = new Intent();//採用intent發送數據
- Bundle bundle = new Bundle();
- bundle.putString("hello", "world");
- intent.putExtras(bundle);
- intent.setAction(Intent.ACTION_EDIT);//只發送給action爲ACTION_EDIT的對象
- MainActivity.this.sendBroadcast(intent);
- }
- }
- //通過內部類,可以實現UI修改
- class TestBroadcast extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Toast.makeText(context, "YES2!", Toast.LENGTH_SHORT).show();
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_EDIT)) {
- Bundle bundle = intent.getExtras();
- btn.setText(bundle.getString("hello")); //更改btn的文字
- }
- }
- }
- }
安卓系統廣播
- String ADD_SHORTCUT_ACTION 動作:在系統中添加一個快捷方式。
- String ALL_APPS_ACTION 動作:列舉所有可用的應用。輸入:無。
- String ALTERNATIVE_CATEGORY 類別:說明 activity 是用戶正在瀏覽的數據的一個可選操作。
- String ANSWER_ACTION 動作:處理撥入的電話。
- String BATTERY_CHANGED_ACTION 廣播:充電狀態,或者電池的電量發生變化。
- String BOOT_COMPLETED_ACTION 廣播:在系統啓動後,這個動作被廣播一次(只有一次)。
- String BROWSABLE_CATEGORY 類別:能夠被瀏覽器安全使用的 activities 必須支持這個類別。
- String BUG_REPORT_ACTION 動作:顯示 activity 報告錯誤。
- String CALL_ACTION 動作:撥打電話,被呼叫的聯繫人在數據中指定。
- String CALL_FORWARDING_STATE_CHANGED_ACTION 廣播:語音電話的呼叫轉移狀態已經改變。
- String CLEAR_CREDENTIALS_ACTION 動作:清除登陸憑證 (credential)。
- String CONFIGURATION_CHANGED_ACTION 廣播:設備的配置信息已經改變,參見 Resources.Configuration.
- Creator CREATOR 無 無
- String DATA_ACTIVITY_STATE_CHANGED_ACTION 廣播:電話的數據活動(data activity)狀態(即收發數據的狀態)已經改變。
- String DATA_CONNECTION_STATE_CHANGED_ACTION 廣播:電話的數據連接狀態已經改變。
- String DATE_CHANGED_ACTION 廣播:日期被改變。
- String DEFAULT_ACTION 動作:和 VIEW_ACTION 相同,是在數據上執行的標準動作。
- String DEFAULT_CATEGORY 類別:如果 activity 是對數據執行確省動作(點擊, center press)的一個選項,需要設置這個類別。
- String DELETE_ACTION 動作:從容器中刪除給定的數據。
- String DEVELOPMENT_PREFERENCE_CATEGORY 類別:說明 activity 是一個設置面板 (development preference panel).
- String DIAL_ACTION 動作:撥打數據中指定的電話號碼。
- String EDIT_ACTION 動作:爲制定的數據顯示可編輯界面。
- String EMBED_CATEGORY 類別:能夠在上級(父)activity 中運行。
- String EMERGENCY_DIAL_ACTION 動作:撥打緊急電話號碼。
- int FORWARD_RESULT_LAUNCH 啓動標記:如果這個標記被設置,而且被一個已經存在的 activity 用來啓動新的 activity,已有 activity 的回覆目標 (reply target) 會被轉移給新的 activity。
- String FOTA_CANCEL_ACTION 廣播:取消所有被掛起的 (pending) 更新下載。
- String FOTA_INSTALL_ACTION 廣播:更新已經被確認,馬上就要開始安裝。
- String FOTA_READY_ACTION 廣播:更新已經被下載,可以開始安裝。
- String FOTA_RESTART_ACTION 廣播:恢復已經停止的更新下載。
- String FOTA_UPDATE_ACTION 廣播:通過 OTA 下載並安裝操作系統更新。
- String FRAMEWORK_INSTRUMENTATION_TEST_CATEGORY 類別:To be used as code under test for framework instrumentation tests.
- String GADGET_CATEGORY 類別:這個 activity 可以被嵌入宿主 activity (activity that is hosting gadgets)。
- String GET_CONTENT_ACTION 動作:讓用戶選擇數據並返回。
- String HOME_CATEGORY 類別:主屏幕 (activity),設備啓動後顯示的第一個 activity。
- String INSERT_ACTION 動作:在容器中插入一個空項 (item)。
- String INTENT_EXTRA 附加數據:和 PICK_ACTIVITY_ACTION 一起使用時,說明用戶選擇的用來顯示的 activity;和 ADD_SHORTCUT_ACTION 一起使用的時候,描述要添加的快捷方式。
- String LABEL_EXTRA 附加數據:大寫字母開頭的字符標籤,和 ADD_SHORTCUT_ACTION 一起使用。
- String LAUNCHER_CATEGORY 類別:Activity 應該被顯示在頂級的 launcher 中。
- String LOGIN_ACTION 動作:獲取登錄憑證。
- String MAIN_ACTION 動作:作爲主入口點啓動,不需要數據。
- String MEDIABUTTON_ACTION 廣播:用戶按下了“Media Button”。
- String MEDIA_BAD_REMOVAL_ACTION 廣播:擴展介質(擴展卡)已經從 SD 卡插槽拔出,但是掛載點 (mount point) 還沒解除 (unmount)。
- String MEDIA_EJECT_ACTION 廣播:用戶想要移除擴展介質(拔掉擴展卡)。
- String MEDIA_MOUNTED_ACTION 廣播:擴展介質被插入,而且已經被掛載。
- String MEDIA_REMOVED_ACTION 廣播:擴展介質被移除。
- String MEDIA_SCANNER_FINISHED_ACTION 廣播:已經掃描完介質的一個目錄。
- String MEDIA_SCANNER_STARTED_ACTION 廣播:開始掃描介質的一個目錄。
- String MEDIA_SHARED_ACTION 廣播:擴展介質的掛載被解除 (unmount),因爲它已經作爲 USB 大容量存儲被共享。
- String MEDIA_UNMOUNTED_ACTION 廣播:擴展介質存在,但是還沒有被掛載 (mount)。
- String MESSAGE_WAITING_STATE_CHANGED_ACTION 廣播:電話的消息等待(語音郵件)狀態已經改變。
- int MULTIPLE_TASK_LAUNCH 啓動標記:和 NEW_TASK_LAUNCH 聯合使用,禁止將已有的任務改變爲前景任務 (foreground)。
- String NETWORK_TICKLE_RECEIVED_ACTION 廣播:設備收到了新的網絡 "tickle" 通知。
- int NEW_TASK_LAUNCH 啓動標記:設置以後,activity 將成爲歷史堆棧中的第一個新任務(棧頂)。
- int NO_HISTORY_LAUNCH 啓動標記:設置以後,新的 activity 不會被保存在歷史堆棧中。
- String PACKAGE_ADDED_ACTION 廣播:設備上新安裝了一個應用程序包。
- String PACKAGE_REMOVED_ACTION 廣播:設備上刪除了一個應用程序包。
- String PHONE_STATE_CHANGED_ACTION 廣播:電話狀態已經改變。
- String PICK_ACTION 動作:從數據中選擇一個項目 (item),將被選中的項目返回。
- String PICK_ACTIVITY_ACTION 動作:選擇一個 activity,返回被選擇的 activity 的類(名)。
- String PREFERENCE_CATEGORY 類別:activity是一個設置面板 (preference panel)。
- String PROVIDER_CHANGED_ACTION 廣播:更新將要(真正)被安裝。
- String PROVISIONING_CHECK_ACTION 廣播:要求 polling of provisioning service 下載最新的設置。
- String RUN_ACTION 動作:運行數據(指定的應用),無論它(應用)是什麼。
- String SAMPLE_CODE_CATEGORY 類別:To be used as an sample code example (not part of the normal user experience).
- String SCREEN_OFF_ACTION 廣播:屏幕被關閉。
- String SCREEN_ON_ACTION 廣播:屏幕已經被打開。
- String SELECTED_ALTERNATIVE_CATEGORY 類別:對於被用戶選中的數據,activity 是它的一個可選操作。
- String SENDTO_ACTION 動作:向 data 指定的接收者發送一個消息。
- String SERVICE_STATE_CHANGED_ACTION 廣播:電話服務的狀態已經改變。
- String SETTINGS_ACTION 動作:顯示系統設置。輸入:無。
- String SIGNAL_STRENGTH_CHANGED_ACTION 廣播:電話的信號強度已經改變。
- int SINGLE_TOP_LAUNCH 啓動標記:設置以後,如果 activity 已經啓動,而且位於歷史堆棧的頂端,將不再啓動(不重新啓動) activity。
- String STATISTICS_REPORT_ACTION 廣播:要求 receivers 報告自己的統計信息。
- String STATISTICS_STATE_CHANGED_ACTION 廣播:統計信息服務的狀態已經改變。
- String SYNC_ACTION 動作:執行數據同步。
- String TAB_CATEGORY 類別:這個 activity 應該在 TabActivity 中作爲一個 tab 使用。
- String TEMPLATE_EXTRA 附加數據:新記錄的初始化模板。
- String TEST_CATEGORY 類別:作爲測試目的使用,不是正常的用戶體驗的一部分。
- String TIMEZONE_CHANGED_ACTION 廣播:時區已經改變。
- String TIME_CHANGED_ACTION 廣播:時間已經改變(重新設置)。
- String TIME_TICK_ACTION 廣播:當前時間已經變化(正常的時間流逝)。
- String UMS_CONNECTED_ACTION 廣播:設備進入 USB 大容量存儲模式。
- String UMS_DISCONNECTED_ACTION 廣播:設備從 USB 大容量存儲模式退出。
- String UNIT_TEST_CATEGORY 類別:應該被用作單元測試(通過 test harness 運行)。
- String VIEW_ACTION 動作:向用戶顯示數據。
- String WALLPAPER_CATEGORY 類別:這個 activity 能過爲設備設置牆紙。
- String WALLPAPER_CHANGED_ACTION 廣播:系統的牆紙已經改變。
- String WALLPAPER_SETTINGS_ACTION 動作:顯示選擇牆紙的設置界面。輸入:無。
- String WEB_SEARCH_ACTION 動作:執行 web 搜索。
- String XMPP_CONNECTED_ACTION 廣播:XMPP 連接已經被建立。
- String XMPP_DISCONNECTED_ACTION 廣播:XMPP 連接已經被斷開。