Android Developers:允許其它應用程序啟動你的Activity

前面的兩節課程集中在故事的一面:從你的應用程序啟動其它應用程序的Activity。但是如果你的應用程序能執行一個動作,它對於其它應用程序非常有用, 你的應用程序應該準備相應來自其它應用程序的請求。例如,如果你構建一個社交應用程序,它能和用戶的朋友分享消息或者圖片,這是你支持ACTION_SEND意圖的最大興趣,所以用戶在其它應用程序開始一個“share”動作,並啟動你的應用程序來執行這個動作。 

 

為瞭允許其它應用程序來啟動你的Activity,你需要在你的清單文件中相應的<activity>元素中添加一個<intent-filter>元素。 

 

當你的應用是被安裝在一個設備的時候,系統定義你的意圖過濾器,並向所有安裝的應用支持的意圖分類嬉戲。當一個應用程序調用startActivity()方法或者startActivityForResult()方法的時候,使用一個隱式Intent,系統找到那個Activity(或者這多個Activity)能響應這個Intent。 

 

添加一個意圖過濾器 

————————————————————————————————————————————————————————————————— 

為瞭正確的定義你的Activty能處理哪個意圖,每個你添加的意圖過濾器應該竟可能的具體,在動作類型和Activity能接受的數據方面。 

 

系統可能發送一個給定的Intent給一個Activity,如果這個Activity有一個意圖過濾器滿足下面Intent對象的條件: 

 

Action 

一個命名將要執行動作的字符串。通常是平臺定義的一個值,例如ACTION_SEND,或者ACTION_VIEW。 

 

在你的意圖過濾器中使用<action>元素指定它。你在這個元素中指定的值必須是動作的完整字符串名稱,使用API常量替代(查看下面的例子)。 

Data 

Intent相關的數據的描述。 

 

在你的意圖過濾器中使用<data>元素來指定它。在這個元素中使用一個或者多個屬性,你能僅僅指定MIME類型,僅僅指定一個URL前綴,僅僅指定一個URI模型,或者這些的組合和其它能公認的指明數據類型。 

 

註意:如果你不需要聲明關於數據Uri的特征(例如當你的Activity處理其它類型的“額外”數據的時候,替代一個URI),你應該僅僅指定android:mimeType屬性來聲明你的Activity處理的數據類型,例如text/plain或者image/jpeg。 

 

Category 

提供一種額外的方式來描述這個Activity處理的Intent的特征,通常和用戶請求相關,或者定位它啟動的地方。這裡有多個系統支持的不同的類別,但是大部分很少使用。然而,所有的隱式意圖被定義為默認的CATEGORY_DEFAULT。 

 

在你的意圖過濾器中使用<category>元素指定它。 

 

在你的意圖過濾器中,你能聲明你的Activity接受的條件,通過將相應的XML元素嵌入到<intent-filter>元素中來聲明它們的每一個。 

 

例如,這裡是一個Activity,擁有一個意圖過濾器,它處理ACTION_SEND意圖,當數據類型是文本或者一個圖片的時候: 

[html]  

<activity android:name="ShareActivity">   

   <intent-filter>   

       <action android:name="android.intent.action.SEND"/>   

       <category android:name="android.intent.category.DEFAULT"/>   

       <data android:mimeType="text/plain"/>   

       <data android:mimeType="image/*"/>   

   </intent-filter>   

</activity>   

每個輸入的Intent僅僅隻大牛股瞭一個動作和一個數據類型,但是它能在每個<intent-filter>中聲明多個<action>,<category>,和<data>元素。 

 

任何兩組動作和數據在它們的行為上是相互獨立的,你應該創建單獨的意圖過濾器來之來指定那個動作是可接受的,當匹配數據類型的時候。 

 

例如,假設你的Activity處理文本和圖片的ACTION_SEND和ACTION_SENDTO意圖。在這種情況下,你必須為兩個動作定義連個單獨的意圖過濾器,因為一個ACTION_SEND意圖必須使用數據Uri來指定容器的地址,使用send或者sendto URI機制。例如: 

[html 

<activity android:name="ShareActivity">   

   <!– filter for sending text; accepts SENDTO action with sms URI schemes –>   

   <intent-filter>   

       <action android:name="android.intent.action.SENDTO"/>   

       <category android:name="android.intent.category.DEFAULT"/>   

       <data android:scheme="sms" />   

       <data android:scheme="smsto" />   

   </intent-filter>   

   <!– filter for sending text or images; accepts SEND action and text or image data –>   

   <intent-filter>   

       <action android:name="android.intent.action.SEND"/>   

       <category android:name="android.intent.category.DEFAULT"/>   

       <data android:mimeType="image/*"/>   

       <data android:mimeType="text/plain"/>   

   </intent-filter>   

</activity>   

註意:為瞭獲取多個意圖,你必須在意圖過濾器中包含CATEGORY_DEFAULT類別。這個startActivity()方法和startActivityForResult()方法對待所有的意圖,好像包含CATEGORY_DEFAULT類別。如果你沒有聲明它,沒有隱式意圖決定你的Activity。 

 

更多關於發送和獲取ACTION_SEND意圖來執行一個社交共享行為的信息,請查閱Receiving Content from Other Apps課程。 

 

在你的Activity中處理意圖 

————————————————————————————————————————————————————————————————— 

為瞭決定在你的Activity中執行什麼動作,你能讀取被用於啟動它的Intent。 

 

當你的Activity啟動,調用getIntent()方法來獲取這個啟動這個Activity的Intent。你能在這個Actvity生命周期的任何時間做,但是你通常應該在早期的回調方法中做,例如onCreate()方法或者onStart()方法。 

 

例如: 

[java]  

@Override   

protected void onCreate(Bundle savedInstanceState) {   

   super.onCreate(savedInstanceState);   

   

   setContentView(R.layout.main);   

   

   // Get the intent that started this activity   

   Intent intent = getIntent();   

   Uri data = intent.getData();   

   

   // Figure out what to do based on the intent type   

   if (intent.getType().indexOf("image/") != -1) {   

       // Handle intents with image data …   

   } else if (intent.getType().equals("text/plain")) {   

       // Handle intents with text …   

   }   

}   

 

返回一個結果 

————————————————————————————————————————————————————————————————— 

如果你想給你調用你的Activity返回一個結果,簡單調用setResult()方法來自定結果碼和結果Intent。當你的操作完成,並且用戶應該返回原來的Activiy的時候,調用finish()方法來關閉(並銷毀)你的Actlvity。例如: 

[java] 

// Create intent to deliver some kind of result data   

Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");   

setResult(Activity.RESULT_OK, result);   

finish();   

 你必須總是給結果指定一個結果碼。通常,它是RESULT_OK或者RESULT_CANCELED。你能提供在需要的時候給Intent提供額外的數據。 

 

註意:這個結果默認設置為RESULT_CANCELED。所以,如果用戶按返回按鈕和你設置這個結果之前完成這個動作,原來的Activity獲取”canceled”結果。 

 

如果你僅僅需要返回一個整數,它指示著多個結果選項的一個,你能設置結果碼為任何大於0的數。如果你使用結果碼來傳遞一個整數,並且你不需要包含Intent,你可以調用setResult()方法並僅僅傳遞一個結果碼。例如: 

[java]  

setResult(RESULT_COLOR_RED);   

finish();   

在這種情況,這裡可能隻要少數可能的結果,所以結果碼是一個本地定義的整數(大於0)。當你在你的自己的應用中給一個Activity返回一個結果的時候,它會工作良好,因為這個獲取結果碼的Activity可以引用公共的常量來確定結果碼的值。 

 

註意:沒有必要檢查你的Activity是否使用startActivity()或者startActivityForResult()方法啟動。如果啟動你的Activity的Inent希望一個結果,簡單調用setResult()方法。如果原來的Activity調用瞭startActivityForResult()方法,那麼系統分配給它你在setResult()方法提供的結果;否則,這個結果被忽視。 

發佈留言