Android官方开发文档Training系列课程中文版:与其它APP交互之允许其它APP启动你的Activity
原文地址:http://android.xsoftlab.net/training/basics/intents/filters.html
在前兩節課程中我們只關注了事情的一面:從你的APP啟動其它APP。但是如果你的APP可以執行一些功能,并且這些功能可以被其它APP所利用,那么你可以做一個功能來響應其它APP的請求。舉個例子,如果你構建了一個社交APP并且可以給用戶的朋友分享消息或者照片,那么這是支持ACTION_SEND意圖的最佳興趣點,所以用戶可以從其它APP中啟動一個”share”行為,然后啟動你的APP來完成這個功能。
為了允許其它APP可以啟動你的Activity,你需要添加一個< intent-filter>元素標簽到清單文件中的對應的< activity>標簽元素下。
當APP被安裝到設備上之后,系統會識別你的意圖過濾器,并且添加該信息到所有支持的內部意圖目錄中。當APP使用了隱式意圖調用了startActivity()或startActivityForResult(),那么系統會尋找那些activity可以響應這個意圖。
添加意圖過濾器
為了可以適當的定義Activity可以處理哪一種意圖,你添加每一個意圖過濾器應該盡可能的指明activity可以接受的行為類型和數據類型。
系統可能通過給定的Intent發送到activity,如果這個activity有一個意圖過濾器正好可以完全匹配以下的Intent對象標準:
Action:
這個行為可以執行的名稱。通常平臺上定義的值比如是ACTION_SEND或ACTION_VIEW。
在意圖過濾器中使用< action>元素標簽來指定該值。該值必須是這個行為的全稱,而不是API常量(請看下面的例子)。
Data:
有關這個意圖的數據描述。
在意圖過濾器中使用< data>元素標簽指定該值。使用該元素的更多屬性,你可以僅僅指定MIME類型,URI前綴類型,URI計劃類型,或者這些類型的組合,以及可以接收的其它數據類型。
Note:如果你不需要聲明Uri數據的指定類型(比如你的activity處理其它種類的附加數據,而不是URI),你應該通過android:mimeType屬性聲明activity可以處理的數據類型,比如text/plain或者image/jpeg。
Category:
提供了一種附加方式來描述activity處理intent,通常與啟動的用戶手勢或者位置有關。這里有幾個系統支持的不同的分類,但是大多數是很少使用的。然而,所有的隱式意圖會在默認情況下使用CATEGORY_DEFAULT定義。
可以在意圖過濾器中使用< category>元素標簽指定該值。
在意圖過濾器中,你可以通過在意圖過濾器中使用相應的XML元素來聲明activity可以接收的意圖標準。
舉個例子,這里的activity可以處理ACTION_SEND意圖,當數據類型為文本或者圖像時。
<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都只會指定一個行為和一個數據類型,但是在每一個過濾器中聲明多個< action>,< category>,和< data>元素的話,這就沒問題了。
如果任意的兩對行為和數據會在他們的行為中相互排斥的話,你應該創建單獨的意圖過濾器來指明哪個行為可以接收,當也匹配到相應的數據類型時。
舉個例子,假設activity在ACTION_SEND行為下或者ACTION_SENDTO行為下都可以處理文本和圖像。在這種情況下,你必須定義兩個單獨的意圖過濾器,因為ACTION_SENDTO意圖必須使用數據Uri指定接收地址通過使用send或sendto URI計劃:
<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>Note:為了可以接收隱式意圖,你必須在過濾器中包含類別CATEGORY_DEFAULT。startActivity()和startActivityForResult()方法會對待所有的Intent,仿佛他們都聲明了CATEGORY_DEFAULT類別。如果你沒有在意圖過濾器中聲明它,那么將不會有隱式意圖傳送到該activity中。
有關更多關于發送和接收ACTION_SEND意圖來執行社會分享行為的相關信息,請參見課程: Receiving Simple Data from Other Apps.
在Activity中處理意圖
為了決定要在activity中采取什么行為,你可以從啟動activity的Intent中讀取信息。
隨著activity被啟動,你可以調用getIntent()方法獲得啟動該Activity的Intent。你可以在activity的任意生命周期內做這樣的事情,但是你通常應該在較早的回調方法中做這些事情,比如onCreate()或onStart()。
@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);// Get the intent that started this activityIntent intent = getIntent();Uri data = intent.getData();// Figure out what to do based on the intent typeif (intent.getType().indexOf("image/") != -1) {// Handle intents with image data ...} else if (intent.getType().equals("text/plain")) {// Handle intents with text ...} }返回結果
如果需要將結果返回給調用該activity的那個activity,那么只需要簡單的調用setResult()方法然后設置一個結果碼以及結果Intent。當你的操作完成并且用戶應該返回原來的那個activity是,調用finish()方法來關閉你的activity,像下面這樣:
// 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中提供附加數據。
Note:默認情況下,結果會設置RESULT_CANCELED。所以,如果用戶在完成功能之前或者在你設置結果之前按下了返回按鈕,那么原來的activity會接收到”canceled”結果。
如果你簡單的需要返回一個整型,這個整型指明了若干個結果選項,那么你可以設置結果碼為比0大的任何值。如果你使用了結果碼來傳遞一個整型值,那么你不再需要包含Intent對象,你可以調用setResult()方法,然后只傳一個結果碼進去:
setResult(RESULT_COLOR_RED); finish();在這個例子中,這可能對結果有損傷,所以結果碼是一個本地變量。這種情況在你自己的APP中運行的話,效果會很好,因為原來的activity可以接收到結果碼,然后引用一個公開的常量來判斷結果碼的值。
Note:這里不需要檢查你的activity是否是通過startActivity()或者startActivityForResult()啟動的。那個啟動你activity的activity可能希望會有個結果返回。如果原來的activity調用了startActivityForResult(),那么系統會傳遞setResult()結果,否則,這個結果會被忽略。
總結
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:与其它APP交互之允许其它APP启动你的Activity的全部內容,希望文章能夠幫你解決所遇到的問題。