Android – 使用特定的URL開啟應用程式在iPhone、Android或Windows Phone 7的環境都支援透過URL中特定的Schema來啟動特定的應用程式, 例如:「zune:\\」、「contnet:\\」…等,該目的告訴系統有一特定的連結要被啟動,請系統動找到註冊 對應該Schema的程式並且啟動它,如果想要夾參數帶入應用程式中,寫法就如同透過QueryString的方式 將Key/Value帶入URL中,由程式啟動時根據特定的參數取得值來完成任務。
要完成這樣的功能,在開發Android時要修改那些部分與概念,往下來概要的說明:
該份檔案描述整個Android應用程式的所有功能、使用的Library、要求手機設備提供的權限控制與存取範圍, 因此,今天要增加對特定URL的處理,也正是從該檔案下手告訴Android系統該應用程式將對某特定的URL Schema 有所反應,當系統接收到該URL時自動啟動應用程式。
A. Intent: Android應用程式裡三個重要元件:activities、services與boardcast services,它們之間傳遞訊息的物件即是:Intent。 Intent可被不同的應用程式建立當作互相溝通的主要介面,它本身是個物件用於保存訊息交換的內容、Anrdoid固定參等, 在三種不同元件使用方式也有所不同,如下: Activity: 透過Context.startActivity()將Intent帶到指定的Activity之中;並且實作Activity.startActivityForResult()接受由另一個 Activity回傳的Intent內容(至於回傳的內容會透過setResult()的方式將Intent放入); Service: 透過Context.startService()去初始化Service並且將Intent傳遞給Service讓它進行處理;另外可透過Context.bindService() 去選擇特定的Service與Intent互相連接; Boardcast Service: 例如透過Context.sendBoardcast()將Intent發送給任何的Boardcast,或是透過Context.sendStickyBroadcast()來送給有興 趣的Boardcast service。由於Intent裡需指定特定的system code不然該Intent就沒有被特定的boardcast service查覺到。
了解Intent怎麼在三種元件中使用後,接下來針對Intent物件的結構進行說明: A-1. Component Name: 該屬性為ComponentName物件,它代表Intent目標的完整名稱,例如:com.example.project.app.FreneticActivity; 例如:由Main的activity移到Second的activity,然而在Second收到Intent它的ComponentName即為完整的Second命 名空間,而Package即與AndroidManifest.xml的相同,但移動到不同的命名空間即不同。如下圖: 可透過
A-2. Action:(重要) Action是Intent中重點部分,它定義該Intent要負責的任務是什麼,例如:我想要撥打電話,即會指定該Intent的Action 為ACTION_CALL並在setData指定Uri為tel:0932xxxxxx,啟動並直接撥打電話。相對的,如果是broadcast receiver一樣透 過Action的指定,讓Intent告訴Android系統當收到電量過低時,要通知自己註冊的broadcast receiver來完成指定的任務。
另外,Action也決定的Intent的資料結構,特別是:data與extras。然而,Action除了上述Android API定義的之外, (隨著Android版本不同有更多的Action可用),其實也可以自訂。
A-3. Category: 用於描述該組件(activity, service, broadcast service)要處理的Intent類型,然而,該Category可任意數量的去描述該組件 要處理的Intent對象。如下列的描述類型:
利用URI為概念的傳遞格式,定義了URI與MIME的資料類型。不同的Action搭配不同類型Data格式。例如:ACTION_EDIT, Datal部分需要包括要編輯的文件的URI;ACTION_CALL則Data為要撥打電話的URI:tel:0932xxxxx;如果是ACTION_VIEW, 則Data為http:URI指定的activity收到後將下載或開啟對應的程式將資料顯示出來。 另外,在找到Intent的對應後,除了取出URI之外,更要看它定義的MIME為何種類型,例如:video/mpeg,則代表要開啟 的資料類型為mpeg的影片資料。 通常透過URI也可以推斷出相關的應用,例如:Content://即是Android的Content Provider機制,應用程式之間如果有實作 支援Content Provider那麼別的應用程式即可以透過Content://來擷取它開放出來的資源。 透過
A-5. Extras: 它是一個Key/Value的資料格式,當作Intent要夾帶參數的用途。某些Action透過特定的Extras來傳遞給目標的activity, 做為初始化或識別的任務,例如:ACTION_TIMEZONE_CHANGED有指定的extra key:time-zone或者是ACTION_HEADSET_PLUG 有指定的extra key:state。這樣做的目的在於讓Intent不一定只能依靠URI傳遞參數,所以當二個Activity互動時,也可以 透過該方式來進行資料的傳遞。
A-6. Flags: Flags通常用於指示Android系統如何執行activity,例如:activity屬於那一個Task來執行;或者如何對待啟動的activity等, 也可以把一些特殊定義的標籤設定於此,讓Intent可以夾帶特定的識別代碼。
介紹了Intent後,其實可以了解Android在三種組件互動或是透過Browser互動,均是透過Intent概念來進行互動。因此, 最後就介紹如果要讓自己的應用程式可以接受URL Schema所影響的Intent要設定的參數有那些,進一步去了解Intent-Filter的特性。
B. Intent-filter: Intent在Anrdoid開發文件裡可分成二個部分: (1) Explicit intents:Intent指定特定目標對象,通常都是內部Project中的activity或是其他組件互相溝通。 。 (2) Implicit intents:Intent不需要特定目標對象,通常用於激活其他應用程式的組件。 Android在使用Explicit intents時,由於目標比較明確比較沒有問題,但在遇到Implicit intents時,系統必須尋找到最匹配的組件 來處理Intent,例如:在AndroidManifest.xml定義Activity、Service或Broadcast Receiver來處理特定的Intent(Intent-Filter)。 透過Intent-Filter定義了組件需要處理的explicit、implicit Intents,但如果組件沒有定義Intent-Filter的話,該組件只能處理explicit intents。
然而,每一個Intent-Filter描述組件(activity, service, broadcast receiver)處理的目標與特性,每一個filter是實例化 類別,filter有三個主要的重點:(1). action;(2). data;(3). category; action: 1: <action android:name="string" /> 定義該組件要面對的Action對象為何。name屬性通常是使用Intent描述的Action屬性,自己的應用程式裡如果有自訂要處理的 Action也可以透過自訂的字串常數來說明。在Intent-Filter中至少要有一個<action>標籤。 category: 1: <intent-filter> 2: <category android:name="android.intent.category.DEFAULT" /> 3: <category android:name="android.intent.category.BROWSABLE" /> 4: </intent-filter> 上述提到有關intent中的category描述不太一樣,在intent中是直接使用上述提到的常數,但在AndroidManifest.xml中定義的 需要使用完整的字串來加以描述,例如:android.intent.category.BROWSABLE與intent中使用的CATEGORY_BROWSABLE相似。 data: 1: <intent-filter> 2: <data android:mimeType="video/mpeg" android:scheme="http" /> 3: <data android:mimeType="audio/mpeg" android:scheme="http" /> 4: </intent-filter> 每一個<data>定義了處理的URI與data type(MIME media type),屬性包括:schema、host、port與path,其格式如下: URI:{schema://host:port/path},定義Android如收到相同URI的格式需通當定義這個data的組件;
[注意] 透過URL啟動的與透過手動啟動的應用程式二者是不同的,前者是依賴著啟動者的執行緒所啟動,後者則是獨立的執行緒, 二者其實控制的功能都是一樣的,最大的差異在於透過URL啟動的應用程式,在長按「實體home鍵」要切換回應用程式時, 它不會出現暫存清單中。
〉範例說明: 1. 實作一個網頁裡面有一個特定的URL,例如:「myapp://Order?SID=201112301333001」; 1: <html xmlns="http://www./1999/xhtml" > 2: <head runat="server"> 3: <title>使用特定的URL開啟應用程式</title> 4: </head> 5: <body> 6: <form id="form1" runat="server"> 7: <div> 8: <!-- 定義特定的URL與Schema --> 9: <a href="myapp://Order?SID=201112301333001">您有一封新單據。</a> 10: </div> 11: </form> 12: </body> 13: </html> 2. 建立透過URL啟動後要處理的Activity與擷取參數的功能; 在OnCreate事件中建立取得由URL啟動應用程式帶入的值,這些資料按照Android的作法會放置於Intent的物件中。 1: @Override
2: protected void onCreate(Bundle savedInstanceState) { 3: super.onCreate(savedInstanceState); 4: setContentView(R.layout.urlopen);
5: //取得要顯示參數的TextView物件 6: TextView tView = (TextView) findViewById(R.id.textView1);
7:
8: //取得URL所帶進來的Intent物件 9: Intent tIntent = this.getIntent(); 10: //取得Schema,值為:myapp 11: String tSchema = tIntent.getScheme();
12: //取得URL 13: Uri myURI = tIntent.getData();
14: if (myURI != null) { 15: //取得URL中的Query String參數 16: String tValue = myURI.getQueryParameter("SID"); 17: tView.setText(tValue);
18: }
19: }
3. 定義AndroidManifest.xml中支援URL的Schema與互相的相關參數; 1: <application android:icon="@drawable/icon" android:label="@string/app_name"> 2: <!-- 主程式--> 3: <activity android:name=".Main" 4: android:label="@string/app_name"> 5: <intent-filter> 6: <action android:name="android.intent.action.MAIN" /> 7: <category android:name="android.intent.category.LAUNCHER" /> 8: </intent-filter> 9: </activity> 10: <!-- 接收由URL啟動應用程式後第一個要進入的Activity --> 11: <activity android:name=".Second"> 12: <intent-filter> 13: <!-- 宣告該Activity的Action主要類型 --> 14: <action android:name="android.intent.action.VIEW"/> 15: <!-- 定義該Activity支援瀏覽模式 --> 16: <category android:name="android.intent.category.BROWSABLE"/> 17: <category android:name="android.intent.category.DEFAULT"/> 18: <!-- 定義要處理的URL Schema --> 19: <data android:scheme="myapp"/> 20: </intent-filter> 21: </activity> 22: </application>
====== 以上是介紹如何透過特定的URL來啟動自己的應用程式,由於該用途很適合結合目前公司既有程式, 因為不想特別公開連線資訊出來時,透過URL夾帶參數給已安裝於手機中的應用程式,再與後端系統 進行互動,既可以做到與設備的結合更可以讓部分安全性得到保護。
References: Android intent filter, associate app with file extension (重要) Intent & Intents and Intent Filters MIME types and ACTION_SEND intent chooser Jollen 的 Android 教學,#28: HelloIntentSelect - 內容選擇器(Content Chooser) Launching Your Own Application via a Custom URL Scheme Launching Other Apps within an iPhone Application Custom URL Scheme - iPhone & Android How to implement my very own URI schema on Android android custom url scheme..? & How do I launch my app via a custom URL in an email Launch custom android application from android browser & Defining custom URL schemes for your AIR mobile applications
Dotblogs Tags: Android
enjoy developing application and learning new technology time. DotBlogs Tags: Android posted on 2012/1/1 16:04 我要推薦 | 閱讀數 : 20524 | 文章分類 [ Android ] 訂閱 Feedback# re: Android – 使用特定的URL開啟應用程式 回覆POU大大您好 請問本文中您提到 wp7 也可以 是否有相關的 MSDN 可以看呢? 我正需要這方面的資訊但找不到相關的資訊 找到的一些國外論壇都是說沒有支援 還請您協助給我一些提示了,謝謝您
2012/3/23 下午 11:11
|
粉絲
# re: Android – 使用特定的URL開啟應用程式 回覆您好, 關於WP7使用custom url schema來開啟程式,只能透過zune://這個來啟動,但這個會啟動Marketplace。因為我自己也在等這個功能阿...
2012/3/24 下午 12:53
|
pou
# re: Android – 使用特定的URL開啟應用程式 回覆
十分感恩你給了我啟示!!但如果這個問題存在體驗不好。[注意] ,最大的差異在於透過URL啟動的應用程式,在長按「實體home鍵」要切換回應用程式時, 它不會出現暫存清單中。 而且手機進程里會顯示兩個,一個是軟體開啟的,一個是瀏覽器開啟的。我用了singleTask来修飾Activity的類型。結果URL開啟的應用是可以HOME 暫存。但是 如果我不停的進入應用會出現許多重複的頁面。這個問題困擾我很久,期待您能給我答案~我的E_mail:007mmh2011@gmail.com。拜謝!!
2012/3/25 上午 01:57
|
毛明浩
# re: Android – 使用特定的URL開啟應用程式 回覆@毛明浩: SingleTask這個標籤的使用,真的要小心.因為我也有遇到多個重覆畫面的問題,我正在撰寫有關SingleTask與Intent之間的關聯, 等我整理出一個心得,我會mail跟您說. 分享給大家.
2012/3/25 上午 11:12
|
pou
# re: Android – 使用特定的URL開啟應用程式 回覆博主您好,关于URL启动app非常感谢您详尽的说明,目前我也遇到楼上的问题,即是:点击url启动app时,即便手机上app已经是开启状态,依然会重新启动一个app进程,并且新启动app不展示在暂存清单中。 这个问题也困扰我很久,因为我希望如果app已经开启,那么点击url时应跳转到已开启app,不知您后来是否对此有解决方案。期待您的回复!
2013/9/29 下午 07:15
|
sunport
# re: Android – 使用特定的URL開啟應用程式 回覆
to sunport :
2013/10/15 上午 09:40
|
pou
# re: Android – 使用特定的URL開啟應用程式 回覆
你好
2014/3/22 下午 09:18
|
lily
|
|