注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/basics/intents/filters.html
之前的兩節課關注于故事的一面:從你的應用啟動另一個應用的activity。但是如果你的應用可以執行一個對另一個應用來說有用的行為,那么你的應用就應該準備好響應由其他應用所發起的行為需求。例如,你構建了一個社交應用,它可以和用戶的朋友分享信息和照片,那么此時你最感興趣的就是支持 ACTION_SEND 的Intent,這樣用戶可以在其他應用初始化一個“ 分享 ”的行為,然后啟動你的應用來執行這個行為。
為了允許其他應用啟動你的Activity,你需要在清單文件中,在對應的
<activity>
標簽內,
添加一個
<intent-filter>
(姑且稱之為Intent過濾器)
標簽。
當你的應用安裝在一個設備上時,系統會識別你的intent過濾器,并且將信息添加至一個內部的目錄,這里面收錄了所有安裝的應用所支持的intents。當一個應用調用 startActivity() 或者 startActivityForResult() ,并且使用的是隱式的intent時,系統會找到哪一個(些)activity可以相應這個intent。
?
一). 添加一個Intent過濾器
為了恰當地定義你的activity可以處理什么intents,每個你添加的intent過濾器,就activity能接受的行為和數據類型而言,應該是越明確越好。
如果Activity的intent過濾器能夠符合下面列舉的 Intent 對象標準,那么系統會將該 Intent 交付給這個activity:
Action
一個字符串,表征了將要執行的行為的名稱。通常是一個系統所定義的值,如: ACTION_SEND 或者 ACTION_VIEW 。
在你的intent過濾器中,用
<action>
標簽來特指接收的行為。在這個標簽中你所特指的值必須是這個行為的全名,而不是
API
常量(見下面的例子)。
Data
這是一個和intent所關聯的數據的描述。
在你的intent過濾器中,用
<data>
標簽來特指它。你可以在這個標簽中使用一個或多個字段,你可以只定義MIME類型,只定義一個URI前綴,只定義一個URI方案,或者是這些和其他類型的結合,它們指出了能接收的數據類型。
Note:
如果你不需要申明關于數據 Uri 細節(比如當你的activity處理其他類型的“extra”數據,而不是一個URI),那么你應該只指明“ android:mimeType ”這一屬性字段,以此來聲明你的activity要處理的數據類型,比如:“ text/plain ”或者“ image/jpeg ”。
Category
提供一個額外的方法來特定處理該intent的Activity,通常與用戶的手勢或者它所啟動的地點相關。系統支持一些不同類型的category,但大多數很少使用。然而,要記住的是所有隱式的intent,默認定義了 CATEGORY_DEFAULT 。
在你的Intent過濾器中,用
<category>
標簽特指它。
?
在你的intent過濾器中,你可以通過在
<intent-filter>
標簽中添加合適的XML標簽,來申明你的
activity
接收什么樣的
intent
。
下面的例子是一個具有intent過濾器的activity,它處理的intent是這樣的,具有 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只特定一個行為和一個數據類型,但是在每個
<intent-filter>
標簽中聲明多個
<action>
,
<data>
或者
<category>
標簽的實例也是可以的。
如果有兩對行為和數據,其行為是相互排斥的,你應該分別創建intent過濾器,將行為和數據類型合理搭配避免沖突。
例如,假設你的應用處理文本和圖像的數據類型,也同時相應 ACTION_SEND 和 ACTION_SENDTO 的行為。在這種情況下,你必須為兩個行為分別定義兩個intent過濾器,因為一個含有 ACTION_SENDTO 的intent必須使用數據 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:
為了接收隱式的intent,你必須在intent過濾器中包含 CATEGORY_DEFAULT 這一category。 startActivity() 和 startActivityForResult() 這兩個方法都將所有的intent處理為包含有 CATEGORY_DEFAULT 的category。如果你不聲明它,你的應用不會收到任何隱式的intent。
更多關于發送和接收 ACTION_SEND 的intents的信息,可以閱讀: Receiving Simple Data from Other Apps
?
二). 處理你的Activity中的Intent
為了決定在你的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 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。當你的操作執行完畢,并且用戶要返回到原來的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會收到“取消”的結果。
如果你只需要返回一個整數,它代表了一些結果項中的一個,那么你可以將結果碼設置為任何一個大于0的數。如果你使用結果碼來返回一個整數,此時你不需要再傳遞一個
Intent
。你可以調用
setResult()
,并且只傳遞一個結果碼,例如:
setResult(RESULT_COLOR_RED);
finish();
在這個例子中,可能僅有少量的一些結果,所以結果碼是一個本地定義的整形(大于0)。這樣做在你給自己的應用的某個activity返回一個結果時,是沒有問題的,因為接收這個結果的activity可以引用公有常量來明確結果碼的值。
Note:
不需要檢查你的activity是被 startActivity() 還是被 startActivityForResult() 所啟動的。如果啟動你的activity的intent需要返回一個值,僅需要調用 setResult() 。如果原始activity調用的是 startActivityForResult() ,那么系統將會發送給它你在 setResult() 中提供的數據,不然的話,這個結果會被忽略。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
