Android業(yè)務(wù)組件化之URL Scheme使用
H5打包的apk使用(Android平臺(tái)通過(guò)UrlSchemes與第三方應(yīng)用相互調(diào)用)
什么是 URL Scheme暖哨?
android中的scheme是一種頁(yè)面內(nèi)跳轉(zhuǎn)協(xié)議赌朋,是一種非常好的實(shí)現(xiàn)機(jī)制,通過(guò)定義自己的scheme協(xié)議篇裁,可以非常方便跳轉(zhuǎn)app中的各個(gè)頁(yè)面沛慢;通過(guò)scheme協(xié)議,服務(wù)器可以定制化告訴App跳轉(zhuǎn)那個(gè)頁(yè)面达布,可以通過(guò)通知欄消息定制化跳轉(zhuǎn)頁(yè)面团甲,可以通過(guò)H5頁(yè)面跳轉(zhuǎn)頁(yè)面等。
URL Scheme應(yīng)用場(chǎng)景:
客戶端應(yīng)用可以向操作系統(tǒng)注冊(cè)一個(gè) URL scheme往枣,該 scheme 用于從瀏覽器或其他應(yīng)用中啟動(dòng)本應(yīng)用伐庭。通過(guò)指定的 URL 字段,可以讓?xiě)?yīng)用在被調(diào)起后直接打開(kāi)某些特定頁(yè)面分冈,比如商品詳情頁(yè)、活動(dòng)詳情頁(yè)等等霸株。也可以執(zhí)行某些指定動(dòng)作雕沉,如完成支付等。也可以在應(yīng)用內(nèi)通過(guò) html 頁(yè)來(lái)直接調(diào)用顯示 app 內(nèi)的某個(gè)頁(yè)面去件。綜上URL Scheme使用場(chǎng)景大致分以下幾種:
● 服務(wù)器下發(fā)跳轉(zhuǎn)路徑坡椒,客戶端根據(jù)服務(wù)器下發(fā)跳轉(zhuǎn)路徑跳轉(zhuǎn)相應(yīng)的頁(yè)面
● H5頁(yè)面點(diǎn)擊錨點(diǎn),根據(jù)錨點(diǎn)具體跳轉(zhuǎn)路徑APP端跳轉(zhuǎn)具體的頁(yè)面
● APP端收到服務(wù)器端下發(fā)的PUSH通知欄消息尤溜,根據(jù)消息的點(diǎn)擊跳轉(zhuǎn)路徑跳轉(zhuǎn)相關(guān)頁(yè)面
● APP根據(jù)URL跳轉(zhuǎn)到另外一個(gè)APP指定頁(yè)面
URL Scheme協(xié)議格式:
先來(lái)個(gè)完整的URL Scheme協(xié)議格式:
xl://goods:8888/goodsDetail?goodsId=10011002
通過(guò)上面的路徑 Scheme倔叼、Host、port宫莱、path丈攒、query全部包含,基本上平時(shí)使用路徑就是這樣子的授霸。
● xl代表該Scheme 協(xié)議名稱(chēng)
● goods代表Scheme作用于哪個(gè)地址域
● goodsDetail代表Scheme指定的頁(yè)面
● goodsId代表傳遞的參數(shù)
● 8888代表該路徑的端口號(hào)
URL Scheme如何使用:
1.)在AndroidManifest.xml中對(duì)<activity />標(biāo)簽增加<intent-filter />設(shè)置Scheme
<activity
android:name=".GoodsDetailActivity"
android:theme="@style/AppTheme">
<!--要想在別的App上能成功調(diào)起App巡验,必須添加intent過(guò)濾器-->
<intent-filter>
<!--協(xié)議部分,隨便設(shè)置-->
<data android:scheme="xl" android:host="goods" android:path="/goodsDetail" android:port="8888"/>
<!--下面這幾行也必須得設(shè)置-->
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
2.)獲取Scheme跳轉(zhuǎn)的參數(shù)
Uri uri = getIntent().getData();
if (uri != null) {
// 完整的url信息
String url = uri.toString();
Log.e(TAG, "url: " + uri);
// scheme部分
String scheme = uri.getScheme();
Log.e(TAG, "scheme: " + scheme);
// host部分
String host = uri.getHost();
Log.e(TAG, "host: " + host);
//port部分
int port = uri.getPort();
Log.e(TAG, "host: " + port);
// 訪問(wèn)路勁
String path = uri.getPath();
Log.e(TAG, "path: " + path);
List<String> pathSegments = uri.getPathSegments();
// Query部分
String query = uri.getQuery();
Log.e(TAG, "query: " + query);
//獲取指定參數(shù)值
String goodsId = uri.getQueryParameter("goodsId");
Log.e(TAG, "goodsId: " + goodsId);
}
3.)調(diào)用方式
網(wǎng)頁(yè)
<a href="xl://goods:8888/goodsDetail?goodsId=10011002">打開(kāi)商品詳情</a>
原生調(diào)用
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("xl://goods:8888/goodsDetail?goodsId=10011002"));
startActivity(intent);
4.)如何判斷一個(gè)Scheme是否有效
PackageManager packageManager = getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("xl://goods:8888/goodsDetail?goodsId=10011002"));
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isValid = !activities.isEmpty();
if (isValid) {
startActivity(intent);
}
說(shuō)明:如果遇到特殊情況參考
實(shí)際使用中的一些小細(xì)節(jié)
當(dāng)自定義的URL配置在LAUNCHER對(duì)應(yīng)的Activity上時(shí)碘耳,上述配置就足夠了显设。
但是當(dāng)自定義的URL配置在非LAUNCHER對(duì)應(yīng)的Activity時(shí),還需要增加額外幾步操作辛辨。
問(wèn)題一:使用自定義的URL啟動(dòng)Activity時(shí)捕捂,默認(rèn)是已FLAG_ACTIVITY_NEW_TASK的方式啟動(dòng)的瑟枫,所以可能存在URL啟動(dòng)的Activity跟應(yīng)用已啟動(dòng)的Activity不再同一個(gè)堆棧的現(xiàn)象。
解決方式:這種情況下指攒,需要在manifest中將Activity多配置一個(gè)taskAffinity屬性力奋,約束URL啟動(dòng)的Activity與應(yīng)用自身的啟動(dòng)的Activity在同一個(gè)堆棧中。
問(wèn)題二:應(yīng)用A使用url的方式喚起應(yīng)用B的Activity時(shí)幽七,可能存在應(yīng)用B的Activity啟動(dòng)了景殷,但是堆棧仍然在后臺(tái)的現(xiàn)象,即應(yīng)用B的Activity沒(méi)有聚焦的問(wèn)題澡屡。
解決方式:這種情況下猿挚,應(yīng)用B的Activity收到啟動(dòng)的請(qǐng)求后,可以主動(dòng)將Activity對(duì)應(yīng)的堆棧移動(dòng)到最前端驶鹉。
1. ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
2. activityManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME);
使用這種方式需要注意的是該api是在Android 3.0(api 11)以后才提供的绩蜻,現(xiàn)在基本上手機(jī)rom版本都是Android4.4以上了,就不太需要關(guān)注3.0一下怎么處理了室埋,且使用這個(gè)需要在manifest中申請(qǐng)android.permission.REORDER_TASKS權(quán)限办绝。
H5部分
Android平臺(tái)可以通過(guò)Url Scheme來(lái)調(diào)用第三方應(yīng)用,設(shè)置步驟如下:
5+應(yīng)用配置支持urlscheme
雙擊應(yīng)用的manifest.json文件姚淆,切換到“代碼視圖”孕蝉,在根節(jié)點(diǎn)下添加plus->distribute->google下添加schemes節(jié)點(diǎn)數(shù)據(jù)如下:
其值為字符串?dāng)?shù)組,每個(gè)字符串為一個(gè)urlscheme腌逢,使用小寫(xiě)字母降淮,可設(shè)置多個(gè)。
保存后提交App云端打包生效
瀏覽器中通過(guò)href啟動(dòng)應(yīng)用
安裝應(yīng)用后搏讶,我們可以在html頁(yè)面中佳鳖,通過(guò)href直接調(diào)用應(yīng)用:
<a href="test://abc">test:<a><br/>
5+應(yīng)用中處理urlscheme啟動(dòng)傳遞的參數(shù)
在其它應(yīng)用中通過(guò)href調(diào)用Url Scheme傳遞過(guò)來(lái)的值,可以通過(guò)plus.runtime.arguments獲取
其值為完整的urlscheme字符串媒惕,如上面href的值啟動(dòng)應(yīng)用后獲取的plus.runtime.arguments值為“test://abc”
代碼示例如下:
document.addEventListener('plusready',function(){
checkArguments();
},false);
// 判斷啟動(dòng)方式
function checkArguments(){
console.log("plus.runtime.launcher: "+plus.runtime.launcher);
var args= plus.runtime.arguments;
if(args){
// 處理args參數(shù)系吩,如打開(kāi)新頁(yè)面等
}
}
// 處理從后臺(tái)恢復(fù)
document.addEventListener('newintent',function(){
console.log("addEventListener: newintent");
checkArguments();
},false);
android實(shí)例
參考 :http://www.reibang.com/writer#/notebooks/24554617/notes/26872651
iOS平臺(tái)請(qǐng)參考: