Wednesday, August 13, 2008

置換 Android 預設的 intents (applications)

Android 開放的軟體平台,讓使用者可以選擇並安裝自己想要應用程式。其實就連原本裝置上的預設應用程式都可以被置換。只是翻了 Android Document 並沒找到任何的置換方法(小弟眼拙 ><)。後來才知道直接在 AndroidManifest.xml 直接設定要處理的 intent 即可。置換之後,會在執行此 intent 時,跳出視窗來選擇要直接的 Activity。

實作

AndroidManifest.xml 的設定如下:

   1: <activity android:name=".contact.TestContactActivity" android:label="@string/app_name">
   2:     <intent-filter>
   3:         <action android:name="android.intent.action.MAIN" />
   4:         <category android:name="android.intent.category.LAUNCHER" />
   5:     </intent-filter>
   6:     <intent-filter>
   7:         <action android:name="android.intent.action.VIEW" />
   8:         <category android:name="android.intent.category.DEFAULT" />
   9:         <data android:mimeType="vnd.android.cursor.dir/person" />
  10:     </intent-filter>
  11: </activity>

7-9 行就是宣告處理 view contacts 的 intent,在此則執行我們定義的 TestContactActivity。

TestContactActivity 則是很簡單顯示 intent 的 Activity:

   1: public class TestContactActivity extends Activity {
   2:     @Override
   3:     public void onCreate(Bundle icicle) {
   4:         super.onCreate(icicle);
   5:         setContentView(R.layout.main);
   6:         TextView tv = (TextView) findViewById(R.id.context);
   7:         tv.setText(getIntent().toString());
   8:     }
   9: }

結果

先執行 Dailer Dailer 後,在 Recent calls 中按下menu,如下:

View contacts

點選 View Contacts 後,接著就會出現 Select Activity 的畫面

Select Activity...

點選 TestContactApp,結果如下

intent replace result

查看 logcat 可以了解大致執行的過程。

   1: W/ActivityManager(  694):   Starting intent: Intent { action=android.intent.action.VIEW data=content://contacts/people launchFlags=4 comp={android/android.app.ResolveListActivity} }
   2: I/ActivityManager(  694): Done launching {android/android.app.ResolveListActivity}: 1021 ms
   3: D/ActivityManager(  694): Stopping: HistoryRecord{400b0ec0 {com.google.android.phone/com.google.android.phone.DialerActivity}}
   4: I/ActivityManager(  694): Starting activity: Intent { action=android.intent.action.VIEW data=content://contacts/people launchFlags=20 comp={com.omachi.test/com.omachi.test.contact.TestContactActivity} }
   5: D/ActivityThread(  795): Performing launch of ActivityRecord{4001b6b0 token=android.os.BinderProxy@40038cf8 {com.omachi.test/com.omachi.test.contact.TestContactActivity}}
   6: I/ActivityManager(  694): Displayed activity {com.omachi.test/com.omachi.test.contact.TestContactActivity}: 865 ms
   7: I/ActivityManager(  694): Done launching {com.omachi.test/com.omachi.test.contact.TestContactActivity}: 970 ms
   8: I/ActivityManager(  694): Removing activity: Intent { action=android.intent.action.VIEW data=content://contacts/people launchFlags=4 comp={android/android.app.ResolveListActivity} }

在 start intent 時,是指定執行 ResolveListActivity ,也就是選擇要執行 Activity的畫面。轉到 TestContactActivity時,launchFlags 則加上了 FORWARD_RESULT_LAUNCH(16) 。

結語

其實 Android 手機並未出現,到時在手機真正的情況是如何並不知道。不過可以了解到,Android 是想要讓使用者連手機預設的應用程式都可以換為自己使用。不過還是有幾點的問題啦

  1. 每次執行 intent 都要選一次:目前看來,之後應該是會有地方可以設定預設執行的應用程式才對。不然實用性會大大降低。
  2. 事情沒這麼簡單:其實已經很多人在對 Android 平台的 phonebook 產生興趣。不過因為 phonebook 與手機本身的整合度一定是極高,而且現有的 contacts content provider 是無法抽換的,dailer 的 call log 的資料也是在裡頭。所以在與現有 ap 做整合時,還是會有一定的困難度。
  3. 難搞的電信商:很多電信商的手機大都會綁死很多的規格,對這些這麼開放的規格,到時可能會有多少另外的限制,還真的是走著瞧。當然前提是如果他們肯用 Android 平台的話。

No comments: