分享

Android – 使用特定的URL開啟應用程式

 quasiceo 2014-09-01

Android – 使用特定的URL開啟應用程式

在iPhone、Android或Windows Phone 7的環境都支援透過URL中特定的Schema來啟動特定的應用程式,

例如:「zune:\\」、「contnet:\\」…等,該目的告訴系統有一特定的連結要被啟動,請系統動找到註冊

對應該Schema的程式並且啟動它,如果想要夾參數帶入應用程式中,寫法就如同透過QueryString的方式

將Key/Value帶入URL中,由程式啟動時根據特定的參數取得值來完成任務。

 

要完成這樣的功能,在開發Android時要修改那些部分與概念,往下來概要的說明:

 

AndroidManifest.xml File

    該份檔案描述整個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的相同,但移動到不同的命名空間即不同。如下圖:

       image

       可透過setComponent())" target=_blank>setClass()setClassName()getComponent()來操作ComponentName的資料。

 

A-2. Action:(重要)

       Action是Intent中重點部分,它定義該Intent要負責的任務是什麼,例如:我想要撥打電話,即會指定該Intent的Action

      為ACTION_CALL並在setData指定Uri為tel:0932xxxxxx,啟動並直接撥打電話。相對的,如果是broadcast receiver一樣透

      過Action的指定,讓Intent告訴Android系統當收到電量過低時,要通知自己註冊的broadcast receiver來完成指定的任務。

Constant Target component Action
ACTION_CALL activity 啟動一個撥打電話。
ACTION_EDIT activity 顯示資料提供用戶有編輯能力。
ACTION_MAIN activity 預設第一個啟動的activity,沒有資料輸入和回傳資料輸出。
ACTION_SYNC activity 設備與伺服務同步資料。
ACTION_VIEW activity 顯示資料不支援編輯能力。
ACTION_DIAL activity 啟動撥號程式並填入撥號的號碼。
ACTION_BATTERY_LOW broadcast receiver 當電量過低時發出的警告。
ACTION_HEADSET_PLUG broadcast receiver 設備已經插入了耳機,或將它拔掉。
ACTION_SCREEN_ON broadcast receiver 螢幕被打開。
ACTION_TIMEZONE_CHANGED broadcast receiver 時區設置發生了變化。

      另外,Action也決定的Intent的資料結構,特別是:dataextras。然而,Action除了上述Android API定義的之外,

      (隨著Android版本不同有更多的Action可用),其實也可以自訂。

 

A-3. Category

        用於描述該組件(activity, service, broadcast service)要處理的Intent類型,然而,該Category可任意數量的去描述該組件

        要處理的Intent對象。如下列的描述類型:

Constant Meaning
CATEGORY_BROWSABLE 目標activity可以安全地被透過Browser中顯示的link(或uri)來啟動,例如:透過image或mail來啟動對應的應用程式。
CATEGORY_GADGET activity可以被嵌入至另一個hosts gadgets中的activity。
CATEGORY_HOME activity呈現於HOME screen,也就是當用戶按下實體鍵盤中的HOME時,用戶第一個看到的畫面。例如:GO桌面即是這種類型的組件。
CATEGORY_LAUNCHER activity是task的初始activity,並且是application launcher的top-level。該類型常設定應用程式第一個啟動的activity,並且配合ACTION_MAIN一同定義該activity。
CATEGORY_PREFFRENCE 目標activity是一個preference panel。


A-4. Data

       利用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://來擷取它開放出來的資源。

       透過setData()來定義URI,使用setType()定義 MIME類型或是setDataAndType()同時定義二者。   

 

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是實例化IntentFilter

類別,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 (重要)

Application Fundamentals

定義Anrdoid清單-AndroidManifest

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:

 

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開啟應用程式 回覆

了解了,謝謝您 : )

2012/3/24 下午 02:21 | 粉絲

# 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開啟應用程式 回覆

很高興這麼快看到您的回覆!!期待您的分享。此間我也再匯總下,屆時希望能與您交流~

2012/3/25 下午 11:59 | 毛明浩

# re: Android – 使用特定的URL開啟應用程式 回覆

博主您好,关于URL启动app非常感谢您详尽的说明,目前我也遇到楼上的问题,即是:点击url启动app时,即便手机上app已经是开启状态,依然会重新启动一个app进程,并且新启动app不展示在暂存清单中。

这个问题也困扰我很久,因为我希望如果app已经开启,那么点击url时应跳转到已开启app,不知您后来是否对此有解决方案。期待您的回复!

2013/9/29 下午 07:15 | sunport

# re: Android – 使用特定的URL開啟應用程式 回覆

to sunport :
您好,关于这个问题,我想可以透过将该Activity设定为Top的方式,让它可以被intent时可以直接使用. 您可以试看看.

2013/10/15 上午 09:40 | pou

# re: Android – 使用特定的URL開啟應用程式 回覆

你好
請問你範例程式中的Order有什麼特別的用意?
是你app中的一個方法嗎?

2014/3/22 下午 09:18 | lily

# re: Android – 使用特定的URL開啟應用程式 回覆

to lily :
還想請問一下
若要用URL連程式 程式需上架嗎?
可以直接在瀏覽器打URL嗎?
還是一定要用網頁連?

2014/3/23 下午 09:53 | lily

# re: Android – 使用特定的URL開啟應用程式 回覆

to lily :
Order沒有特別的意思,可以按照自己的需求調整。

Android如果你要串聯的話不需要上架,只需要用戶有安裝就可以了。因為在安裝後才會註冊針對特定的Scheme進行處理。

如果您直接在Browser上打URL是沒有用處的。

2014/3/24 下午 12:31 | pou

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多