2016年4月28日 星期四

【Android】開啟第三方APP

讓APP的內容或服務可以被其他APP開啟跟呼叫,在Android上是很重要的一項功能,──雖然沒什麼人真的在做。

因為技術上它有很多Google進階設計時模糊曖昧的地方!API或文件都沒有精準說明,也沒有範例可以參考。

所以下面的筆記只是個人使用心得,離參考文件還有很長的距離...



在AndroidManifest檔中加入的Activity設定值標籤內,可以再加入intent-filter的標籤。

預備要被第三方APP呼叫的Activity中,必須要在intent-filter標籤內加入額外的參數。(會這樣說是因為基本用法中,除了靠點擊啟動的Activity需要加入main和launcher參數以外,其餘的Activity並不需要加入額外的參數,甚至連intent-filter都可以不需要。)


<intent-filter>
     <action android:name="android.intent.action.SEND"/>
     <action android:name="android.intent.action.VIEW"/>
     <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
SEND跟VIEW似乎只要擇一加入即可,差別只在於Activity中如果有UI要顯示,「使用」這個Activity的Intent中若是傳入SEND,則這個UI不會被顯示。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//!!!關鍵在這個Flag
intent.addCategory(Intent.CATEGORY_DEFAULT);           
ComponentName cn = new ComponentName("tw.android.demo2", "tw.android.demo2.MainActivity2");           
intent.setComponent(cn);
startActivity(intent);

其實呼叫第三方APP的Activity方法很多,但關鍵應該在於addFlag的動作!

(還沒機會使用到其他型態的Flag,如果有機會用到,會補上結果。)

另外,ComponentName的實體建構子中要傳入兩個參數,一個是第三方APP project名稱,一個則是Activity的完整專案路徑與名稱。

(會強調完整專案路徑與名稱,是因為邏輯上來說,Activity可以分散在多個子project路徑內,例如tw.android.demo2下可以有tw.android.demo2.test,但將Activity放在裏頭,不知道為何AndroidManifest檔內的設定會失敗...一直沒有機會來回頭釐清這一段的正確使用方式和原則。──好像有點本末倒置,不去先釐清更基本的東西,卻在研究比較進階的使用方法。)




另一個奇妙的問題是...當Activity被啟動後,啟動的目的為何?

絕對不是僅僅為了看個UI介面。(有時候會有選單來選擇資料回傳,這時候當然就是要操作UI。但這裡不是指這種情況。)

例如要使用不對外公開的API來跟後台交換資料,這時候就需要建立Thread來完成網路傳輸工作。

奇妙的是...

這種讓第三方啟動的Activity竟然無法在基本生命週期階段中啟動獨立Thread。(寫了個Thread程式,卻無法被啟動,但也沒看到錯誤訊息產生。)

所以這時候就需要使用Service,特別推薦IntentService。(前者可能要等任務完成、關閉Activity後才會跟著關閉,但後者會先在任務完成後關閉自己、同時執行關閉Activity的工作。)



........

怎麼使用IntentService?

別鬧了!去別的地方找資料。