Uri詳解之二——通過自定義Uri外部啓動APP與Notification啓動

一、自定義Uri與外部啓動

1、概述

上篇我們講了Uri的結構,在這篇中,我們將看看如何利用自定義的URI來啓動我的的應用。 有時,我們要通過外部Uri鏈接來啓動我們的應用,主要是通過Uri隱式Intent匹配的方式:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. Uri uri = Uri.parse("qijian://test.uri.activity?action=1");  
  2. Intent intent = new Intent("android.qijian.schemeurl.activity");  
  3. intent.setData(uri);  
  4. startActivity(intent);  
這裏通過隱式Intent匹配來啓動應用,在這裏我們自定義了一個Uri結構:qijian://test.uri.activity?action=1
我們的應用在隱式匹配Intent時,使用的語法爲:
[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <activity  
  2.     android:name=".SecondActivity"  
  3.     android:label="@string/title_activity_second">  
  4.     <intent-filter>  
  5.         <action android:name="android.qijian.schemeurl.activity" />  
  6.         <category android:name="android.intent.category.DEFAULT" />  
  7.         <data  
  8.             android:scheme="qijian"  
  9.             android:host="test.uri.activity" />  
  10.     </intent-filter>  
  11. </activity>  
我們這裏在匹配Intent時,使用指定scheme和host來精確匹配過來的Uri,以防止同名scheme就能啓動我們的activity,即本來可能要啓人家應用,確我們也橫插一腳,用戶體驗很不好,一定要做到精確匹配,以防大家URI一樣出現多個應用讓用戶選擇的情況。
這樣,第三方就能通過這個Uri來匿名啓動我們的Activity了。

2、實例

(1)、新建用於外部啓動的Activity
首先,我們先建一個應用,命名爲:SchemeURL,在這個應用中我們新建一個Activity命名爲:secondActivity,其XML代碼如下:
(這個Activity是爲了在外部啓動,爲了標識這個Activity是這個應用的,把背景色改成了黃色,文字改上了“SchemeURL 的Activity”)

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#ffff00"  
  6.     tools:context="com.harvic.com.schemeurl.SecondActivity">  
  7.   
  8.     <TextView  
  9.         android:text="SchemeURL 的Activity"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content" />  
  12. </RelativeLayout>  
(2)、在AndroidManifest.xml中添加Intent-filter過濾代碼:
在SecondAcitivity中添加上Intent-filter用於隱式啓動Intent,由於我們定義的Uri格式爲:qijian://test.uri.activity?action=1,所以我們固定schemeurl和host,通過query來傳遞參數即可;
除了Uri匹配,我這裏還添加上了Action:“android.qijian.schemeurl.activity”,所以我們在第三方隱式匹配時要同時通過Uri和action來同時匹配才能通過這裏的Intent-filter
[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <activity  
  2.     android:name=".SecondActivity"  
  3.     android:label="@string/title_activity_second">  
  4.     <intent-filter>  
  5.         <action android:name="android.qijian.schemeurl.activity" />  
  6.         <category android:name="android.intent.category.DEFAULT" />  
  7.         <data  
  8.             android:scheme="qijian"  
  9.             android:host="test.uri.activity" />  
  10.     </intent-filter>  
  11. </activity>  
(3)新建應用:UseSchemeURL,通過自定義的Uri來從外部調起SecondActivity
這個應用的外觀是這個樣子的:當點擊按鈕時,調起SchemeURL的SecondActivity:

代碼爲:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. Button btn = (Button) findViewById(R.id.btn_try);  
  2. btn.setOnClickListener(new View.OnClickListener() {  
  3.     @Override  
  4.     public void onClick(View v) {  
  5.         Uri uri = Uri.parse("qijian://test.uri.activity?action=1");  
  6.         Intent intent = new Intent("android.qijian.schemeurl.activity");  
  7.         intent.setData(uri);  
  8.         startActivity(intent);  
  9.     }  
  10. });  
(4)、進階:通過Uri來傳遞參數,並處理
在上面,我們已經能夠通過Uri來進入我們的應用,我們上面只是固定了Uri的scheme部分和host部分,對於其它部分並沒有固定,所以我們可以通過其它部分來傳遞參數,進而完成指定的功能:比較進入指定的頁面或做出指定的操作,等
比如,我們在SchemeURL中,對Uri進行接收,並將結果顯示出來:
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. public class SecondActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_second);  
  7.         Intent intent = getIntent();  
  8.         if (null != intent) {  
  9.             Uri uri = intent.getData();  
  10.             if (uri == null) {  
  11.                 return;  
  12.             }  
  13.             String acionData = uri.getQueryParameter("action");  
  14.   
  15.             TextView tv = (TextView)findViewById(R.id.qijian_test_tv);  
  16.             tv.append("\n傳過來的action值爲:" + acionData);  
  17.         }  
  18.     }  
  19. }  
結果截圖如下:

源碼在文章底部給出;

二、特殊應用:Notification與應用啓動

有關通過Uri啓動APP的經典應用,應當數通過推送消息啓動我們應用的指定頁面或做出特定的操作了。這部分,我們就看看如何通過推送的通知欄消息來進入我們的應用。

效果如下:


  • 首先:SchemeURL工程代碼都不變,我們依然通過隱式匹配Intent來啓動SecondActivity.
  • 然後:在UseSchemeURL工程中新加一個按鈕,當點擊時,發送Notification通知,點擊跳轉到SchemeURL工程的SecondActivity 
其中發送Notification代碼如下:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. private void pushNotify() {  
  2.     NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  3.     NotificationCompat.Builder builder;  
  4.     builder = new NotificationCompat.Builder(this);  
  5.     builder.setSmallIcon(R.drawable.ic_launcher)  
  6.             .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))  
  7.             .setContentTitle("harvic")  
  8.             .setContentText("test schemeURL")  
  9.             .setTicker("有新消息")  
  10.             .setOngoing(false)  
  11.             .setWhen(System.currentTimeMillis())  
  12.             .setPriority(Notification.PRIORITY_DEFAULT)  
  13.             .setAutoCancel(true);  
  14.   
  15.     Uri uri = Uri.parse("qijian://test.uri.activity?action=1");  
  16.     Intent intent = new Intent("android.qijian.schemeurl.activity");  
  17.     intent.setData(uri);  
  18.     PendingIntent pendingIntent = PendingIntent.getActivity(this0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
  19.     builder.setContentIntent(pendingIntent);  
  20.     Notification notification = builder.build();  
  21.     notifyManager.notify(1111, notification);  
  22. }  
有關Notification的知識,我就不再講了,最重要的是PendingIntent的封裝!
即如下代碼:
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. Uri uri = Uri.parse("qijian://test.uri.activity?action=1");  
  2. Intent intent = new Intent("android.qijian.schemeurl.activity");  
  3. intent.setData(uri);  
  4. PendingIntent pendingIntent = PendingIntent.getActivity(this0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
在這裏大家也可以看到,這是利用隱式Intent匹配的方式來啓動我們的Activity的!所有的APP在通知欄進入到自己的應用,都是通過這個方式來的!
源碼在文章底部給出

三、有關path、pathPrefix、pathPattern 之間的區別

細心的同學可能在AndroidManifest.xml中已經發現,Intent-filter的data域除了scheme、host、port這些已知的還有三個參數我們沒用過——path、pathPrefix、pathPattern;它們也是用來隱式匹配Intent的,即:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <activity  
  2.     android:name=".SecondActivity"  
  3.     android:label="@string/title_activity_second">  
  4.     <intent-filter>  
  5.         <action android:name="android.qijian.schemeurl.activity" />  
  6.         <category android:name="android.intent.category.DEFAULT" />  
  7.         <data  
  8.             android:scheme="qijian"  
  9.             android:host="test.uri.activity"  
  10.             android:path=""  
  11.             android:pathPrefix=""  
  12.             android:pathPattern=""/>  
  13.     </intent-filter>  
  14. </activity>  
這裏主要說的區別是 path、pathPrefix、pathPattern 之間的區別
  • path: 用來匹配完整的路徑,如:http://example.com/blog/abc.html,這裏將 path 設置爲 /blog/abc.html 才能夠進行匹配;
  • pathPrefix: 用來匹配路徑的開頭部分,拿上面的 Uri 來說,這裏將 pathPrefix 設置爲 /blog 就能進行匹配了;
  • pathPattern: 用表達式來匹配整個路徑,這裏需要說下匹配符號與轉義。 
匹配符號: 
1、“” 用來匹配0次或更多,如:“a” 可以匹配“a”、“aa”、“aaa”… 
2、“.” 用來匹配任意字符,如:“.” 可以匹配“a”、“b”,“c”… 
3、因此 “.*” 就是用來匹配任意字符0次或更多,如:“.*html” 可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”… 
轉義: 
因爲當讀取 Xml 的時候,“\” 是被當作轉義字符的(當它被用作 pathPattern 轉義之前),因此這裏需要兩次轉義,讀取 Xml 是一次,在 pathPattern 中使用又是一次。如:“” 這個字符就應該寫成 “\”,“\” 這個字符就應該寫成 “\\”。

樣例:匹配 http 以 “.pdf” 結尾的路徑

如果我們想要匹配 http 以 “.pdf” 結尾的路徑,使得別的程序想要打開網絡 pdf 時,用戶能夠可以選擇我們的程序進行下載查看。

我們可以將 scheme 設置爲 “http”,pathPattern 設置爲 “.*\.pdf”,整個 intent-filter 設置爲:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <intent-filter>  
  2.      <action android:name="android.intent.action.VIEW"></action>  
  3.      <category android:name="android.intent.category.DEFAULT"></category>  
  4.      <data android:scheme="http" android:pathPattern=".*\\.pdf"></data>  
  5. </intent-filter>  
如果你只想處理某個站點的 pdf,那麼在 data 標籤裏增加 android:host="yoursite.com" 則只會匹配 http://yoursite.com/xxx/xxx.pdf,但這不會匹配 www.yoursite.com,如果你也想匹配這個站點的話,你就需要再添加一個 data 標籤,除了 android:host 改爲 “www.yoursite.com” 其他都一樣。

四、特殊:如何從網頁中通過Uri啓動我們的應用

如果想要從網頁中點擊一個鏈接跳轉到我們的應用,那除了Intent-filter中的各種匹配工作,還應該加上一個屬性:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <category android:name="android.intent.category.BROWSABLE"/>  
即,以我們的SecondActivity爲例,它完整的AndroidManifest.xml的配置方式爲:
[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <activity  
  2.     android:name=".SecondActivity"  
  3.     android:label="@string/title_activity_second">  
  4.     <intent-filter>  
  5.         <action android:name="android.qijian.schemeurl.activity" />  
  6.         <category android:name="android.intent.category.DEFAULT" />  
  7.         <category android:name="android.intent.category.BROWSABLE"/>  
  8.         <data  
  9.             android:scheme="qijian"  
  10.             android:host="test.uri.activity"/>  
  11.     </intent-filter>  
  12. </activity>  

參考文章:《intent-filter 之 data 「scheme, host, port, mimeType, path, pathPrefix, pathPattern」》


源碼內容:(兩個文件夾分別是)

1、Part1:自定義Uri與外部啓動
2、PART2:特殊應用:Notification與應用啓動

每個文件夾裏面包含兩個工程:

1、SchemeURL:這裏提供第三方調用的SecondActivity

2、UseScheme:在這個APP裏通過隱式匹配調用SchemeURL的SecondActivity


如果本文有幫到你,記得關注哦

源碼下載地址:http://download.csdn.net/detail/harvic880925/8551159

請大家尊重原創者版權,轉載請標明出處:http://blog.csdn.net/harvic880925/article/details/44781557  謝謝

Uri詳解之二——通過自定義Uri外部啓動APP與Notification啓動
發佈了18 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章