Android - 和其他APP交互 - 讓其他app啟動你的activity


前面的兩篇文章主要講了一個方面:從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()提供的結果傳遞給它,否則,會忽視返回值。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM