前面的兩篇文章主要講了一個方面:從app中啟動其他app。但是如果你的app可以處理對其他app有用的操作,你的app也應該響應其他app的操作請求。例如,如果你創建了一個社交app可以分享信息和圖片給用戶的朋友,支持ACTION_SENDintent,讓用戶在其他app初始化分享操作然后啟動你的app來執行,是一件很有趣的事情。
為了其他app可以啟動activity,應該在manifest文件中添加<intent-filter>元素和響應的<activity>元素。
當app安裝到設備上后,系統會識別intent filter然后把信息加到一個所有安裝的app都支持的全局目錄中。當app用模糊的intent調用startActivity()或者startActivityForResult()時,系統就會查詢哪個activity(或哪些)可以響應這個intent。
添加一個Intent Filter
為了要正確的定義哪些intent你的activity可以處理,每個添加的intent filter在接收的操作類型和數據類型上應該盡量的明確。
系統可能會把Intent傳給activity如果activity有一個intent filter完全滿足這個intent的標准:
Action
要指定的動作的名字。通常是平台預定義的值比如ACTION_SEND或者ACTION_VIEW。
在intent filter中用<action>元素來指定。在這個元素中指定的值必須是動作的全名,而不是API常量。(看后面的例子)。
Data
和intent相關的數據描述
在intent filter中的用<data>元素來指定。在這個元素中使用一個或多個屬性,可以只指定MIME類型,URI前綴,或者這些和其他可接受數據類型的組合。
注意:如果不不聲明數據Uri的細節(比如用戶處理其他類型的數據,而不是URI),應該只指明android:mimeType屬性來聲明activity處理的數據類型,比如text/plain或image/jpeg。
Category
提供了一個附加的方式來表示activity處理的intent的特性,通常和用戶手勢或開始的位置相關。系統支持好幾個不同的category,但是很少用到。但是,所有明確的intent都默認定義為CATEGORY_DEFAULT。
在intent filter中用<category>元素來指定。
在intent filter中,可以通過在<intent-filter>中用每個相應的XML元素來定義你的activity可以接收什么樣的標准。
例如,這里有一個activity,它通過intent filter定義了能處理ACTION_SEND的intent,並且數據類型為字符串或圖片:
1 <activity android:name="ShareActivity"> 2 <intent-filter> 3 <action android:name="android.intent.action.SEND"/> 4 <category android:name="android.intent.category.DEFAULT"/> 5 <data android:mimeType="text/plain"/> 6 <data android:mimeType="image/*"/> 7 </intent-filter> 8 </activity>
每個引入的intent都指定了一個動作類型和數據類型,但是可以定義多個<action>,<category>,和<data>元素在每個<intent-filter>中。
如果兩組動作和數據在他們的行為中相互沖突,應該創建另外一個intent-filter來指明接收哪個操作時對應哪些數據類型。
例如,假如activity可以處理ACTION_SEND和ACTION_SENDTO intent以及字符串和圖片。這種情況下,應該為這兩個操作定義兩個不同的intent filter,因為ACTION_SENDTO intent在用必須使用URI數據來指定收件人地址,例如:
1 <activity android:name="ShareActivity"> 2 <!-- filter for sending text; accepts SENDTO action with sms URI schemes --> 3 <intent-filter> 4 <action android:name="android.intent.action.SENDTO"/> 5 <category android:name="android.intent.category.DEFAULT"/> 6 <data android:scheme="sms" /> 7 <data android:scheme="smsto" /> 8 </intent-filter> 9 <!-- filter for sending text or images; accepts SEND action and text or image data --> 10 <intent-filter> 11 <action android:name="android.intent.action.SEND"/> 12 <category android:name="android.intent.category.DEFAULT"/> 13 <data android:mimeType="image/*"/> 14 <data android:mimeType="text/plain"/> 15 </intent-filter> 16 </activity>
注意:為了可以接收模糊的intent,必須在intent filter中包括CATEGORY_DEFAULT。方法startActivity()和startActivityForResult()只處理帶有CATEGORY_DEFAULT的intent。如果沒有聲明它,那么沒有模糊的intent會傳給你的activity。
更多關於使用發送和接收ACTION_SEND intent來執行社會化分享行為,查看Receiving Content from Other Apps。
在Activity中處理Intent
為了決定在activity中執行什么動作,可以查看啟動它的Intent。
當activity啟動時,調用getIntent()來獲取啟動activity的Intent。在activity的聲明周期的任何時候都可以查看,但是通常是在早期的回調方法(onCreate()或onStart())中查看。
例如:
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 5 setContentView(R.layout.main); 6 7 // 獲取啟動這個activity的Intent 8 Intent intent = getIntent(); 9 Uri data = intent.getData(); 10 11 // 根據intent的類型決定做什么 12 if (intent.getType().indexOf("image/") != -1) { 13 // 處理帶有圖片數據的Intent。。。 14 } else if (intent.getType().equals("text/plain")) { 15 // 處理帶有字符串的Intent。。。 16 } 17 }
返回結果
如果要返回到調用你的activity,簡單的調用setResult()來指定結果代碼和結果Intent。當操作完成了然后用戶需要返回到以前的activity,調用finish()來關閉(然后銷毀)這個activity。例如:
1 // 創建intent來傳遞結果數據 2 Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"); 3 setResult(Activity.RESULT_OK, result); 4 finish();
必須要指定結果代碼和結果,總體上,是RESULT_OK或RESULT_CANCELED。然后如果需要的話可以用Intent添加附加數據。
注意:結果默認設置為RESULT_CANCELED。所以,如果用戶在完成操作和設置結果前點了返回按鈕,原來的activity會收到"canceled"結果。
如果只是需要返回一個代表結果選項的數字,可以把結果碼設置為任何大於0的值。如果使用結果碼傳遞一個數字的話就不需要包含Intent了,可以調用setResult()然后只傳遞一個結果碼。例如:
1 setResult(RESULT_COLOR_RED); 2 finish();
這種情況下,只有很少的可能的結果,所以結果碼是本定定義好的數字(大於0)。這個在返回給自己app中的activity是很好用,因為activity接收到結果后可以根據公有的常量來決定返回碼的值。
注意:不需要查看activity是由startActivity()還是startActivityForResult()啟動的。直接調用setResult()因為啟動activity的intent可能需要返回值。如果原始的activity調用了startActivityForResult(),那么系統會把setResult()提供的結果傳遞給它,否則,會忽視返回值。