1. 程式人生 > >Intent和BroadcastReceiver

Intent和BroadcastReceiver

數據 類型 端口 protected sticky 進程 contex register 結構化

Intent簡介

Intent是一種消息傳遞機制,作用:

  • 使用類名顯示啟動一個特定的Service或Activity
  • 啟動Activity或Service來執行一個Intent
  • 廣播某個事件已經發生

使用Intent啟動Activity

顯式啟動Activity

Intent intent = new Intent(MyActivity.this, MyOtherActivity.class);
startActivity(intent);

調用新Activity的finish或按下返回按鈕將關閉該Activity,並出棧。

隱式的Intent和運行時綁定

隱式調用,就是讓匿名的應用程序組件響應動作請求。如撥打電話:

Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:xxxx"));
startActivity(intent);

隱式調用需要一個執行的動作,也可提供執行動作需要的數據URI。還可以通過向Intent添加extra來向目標Activity發送數據。

確定Intent能否解析

有的時候需要判斷intent能否解析:

PackageManager pm = getPackageManager();
ComponentName cn = intent.resolveActivity(pm);

從Activity返回結果

調用startActivityForResult,回調為onActivity。如選取聯系人:

Uri uri = Uri.parse("content://contacts/people");
Intent intent = new Intent(Intent.ACTION_PICK,uri);
startActivityForResult(intent,REQUEST_CODE);

然後請求完成後:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
        //處理返回的結果
 }

Android 原生Action

  • ACTION_ALL_APPS 打開一個列出所有已安裝應用程序的Activity
  • ACTION_ANSWER 打開一個處理來電的Activity
  • ACTION_BUG_REPORT 顯示一個可以報告bug的Activity
  • ACTION_CALL 打開一個電話撥號程序
  • ACTION_CALL_BUTTON 用戶按下撥打按鈕觸發,調用撥號Activity
  • ACTION_DELETE 啟動一個Activity,允許刪除Intent數據URI中指定的數據
  • ACTION_DIAL 打開一個撥號程序
  • ACTION_EDIT 請求一個Activity,要求該Activity可以編輯Intent的數據URI中的數據
  • ACTION_INSERT 打開一個能夠在Intent的數據URI指定的遊標處插入新項的Activity
  • ACTION_PICK 啟動一個子Activity,可以從Intent的數據URI指定的Content Provider中選擇
  • ACTION_SEARCH 通常用於啟動特定的搜索Activity
  • ACTION_SEARCH_LONG_PRESS 允許截獲對硬件搜索鍵的長按操作
  • ACTION_SENDTO 啟動一個Activity來向Intent的數據URI所指定的聯系人發送消息
  • ACTION_SEND 啟動一個Activity,該Activity會發送Intent中指定的數據
  • ACTION_VIEW 視圖要求以最合理的方式查看Intent的數據URI中提供的數據
  • ACTION_WEB_SEARCH 打開一個瀏覽器,進行搜索

使用Intent廣播事件

Intent可以在進程之間發送結構化的消息,可以通過實現Broadcast Receiver來監聽和響應應用程序內的Broadcast Intent。

廣播Intent:

Intent intent = new Intent();
intent.putExtra(key, value);
sendBroadcast(intent);

處理廣播Intent:

private class MyBroadcastReceiver extends BroadcastReceiver{
      @Override
      public void onReceive(Context context, Intent intent) {
            //處理事件
      }
}

註冊廣播兩種方式:

代碼中註冊

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(action);
//註冊
registerReceiver(receiver,intentFilter);
//取消註冊
unregisterReceiver(receiver);

Manifest註冊

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    </intent-filter>
</receiver>

這種方式Receiver總是活動的,並且一直可以接受廣播事件。

廣播有序的Intent

sendOrderdBroadcast可以按照優先級順序發送廣播事件。

<receiver android:name=".MyBroadcastReceiver">
     <intent-filter>
           android:priority = "100">
           <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
      </intent-filter>
</receiver>

廣播Sticky Intent

Sticky Intent可以保存它們最後一個廣播的值,一旦有新的接收器被註冊為接收該廣播時,它們會把這些值作為Intent返回。使用sendStickyBroadcast廣播,刪除使用removeStickyBroadcast。

Pending Intent

Pending Intent用於包裝在響應將來的事件時觸發的Intent。

Intent intent = new Intent(this,MyOtherActivity.class);
PendingIntent.getActivity(this,requestCode,intent,flags);

Intent intent = new Intent(this,MyService.class);
PendingIntent.getService(this,requestCode,intent,flags);


Intent intent = new Intent();
PendingIntent.getBroadcast(this,requestCode,intent,flags);

創建Intent Filter

使用Intent Filter為隱式Intent提供服務

Intent Filter標簽:

  1. action 服務的動作標簽,唯一字串
  2. category 指定提供服務的情況
    • ALTERNATIVE 在特定數據類型上執行的默認動作的可選項
    • SELECTED_ALTERNATIVE 與ALTERNATIVE類似,但是要求可以有多種可能性
    • BROWSABLE 指定瀏覽器內部可用的動作
    • DEFAULT 默認動作
    • HOME 作為本地屏幕的可選項
  3. data data標簽允許指定組件可以執行的數據類型:
    • android:host 指定一個有效的主機名
    • android:mimetype 指定組件可以執行的數據類型
    • android:path 指定URI的有效路徑
    • android:port 指定主機的有效端口
    • android:scheme 要求一種特定的模式(如http)

Android解析Intent Filter

  1. Android將安裝包的可用Filter放到一個列表中
  2. 從列表中移除在解析Intent時相關聯的動作或者類別不匹配的Intent Filter
  3. Intent的數據URI的每一個部分都和Intent Filter的data標簽進行比較

監聽本地Broadcast Intent

可以監聽系統事件,然後進行自己程序的相應動作,經常使用的系統事件:

  • ACTION_BOOT_COMPLETED 系統完成啟動後,會觸發這個動作
  • ACTION_CAMERA_BUTTON 當單擊拍照按鍵時觸發
  • ACTION_DATE_CHANGED 和ACTION_TIME_CHANGED 日期和時間被手動修改,或觸發
  • ACTION_MEDIA_EJECT 用戶彈出外部存儲,會觸發,如果正在操作外部存儲,記得保存和關閉文件句柄
  • ACTION_MEDIA_MOUNTED和ACTION_MEDIA_UNMOUNTED 新的外部存儲成功添加或者移除,會觸發
  • ACTION_NEW_OUTGOING_CALL 向外撥打電話就會觸發
  • ACTION_SCREEN_OFF和ACTION_SCREEN_ON 屏幕關閉或者打開時觸發
  • ACTION_TIMEZONE_CHANGED 時區改變會觸發

有的時候需要在運行時管理Manifest Receiver

使用PackageManager.setComponentEnabledSetting(ReceiverName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP)啟用一個Receiver

使用PackageManager.setComponentEnabledSetting(ReceiverName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP)禁用一個Receiver

Intent和BroadcastReceiver