最近碰到了一个新的需求,用户在浏览器中打开分享出去的内容,如果该用户设备上有我们的客户端则打开客户端并且定位到当前文章,如果没有的话则进行下载。调研过程中遇到了不少的坑,这里share一下。
html源码
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<title>this's a demo</title>
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
</head>
<body>
<div>
<a id="J-call-app" href="javascript:;" class="label">立即打开>></a>
<input id="J-download-app" type="hidden" name="storeurl" value="http://m.chanyouji.cn/apk/chanyouji-2.2.0.apk">
</div>
<script>
(function(){
var ua = navigator.userAgent.toLowerCase();
var t;
var config = {
scheme_IOS: 'will://',
scheme_Adr: 'will://share/testid',
download_url: document.getElementById('J-download-app').value,
timeout: 600
};
function openclient() {
var startTime = Date.now();
var ifr = document.createElement('iframe');
ifr.src = ua.indexOf('os') > 0 ? config.scheme_IOS : config.scheme_Adr;
ifr.style.display = 'none';
document.body.appendChild(ifr);
var t = setTimeout(function() {
var endTime = Date.now();
if (!startTime || endTime - startTime < config.timeout + 200) {
window.location = config.download_url;
} else {
}
}, config.timeout);
window.onblur = function() {
clearTimeout(t);
}
}
window.addEventListener("DOMContentLoaded", function(){
document.getElementById("J-call-app").addEventListener('click',openclient,false);
}, false);
})()
</script>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
基本思路:点击“立即打开“按钮后如果在600毫秒后仍然没有打开客户端则跳到下载链接;这里大家可以任意改造,例如如果在指定时间之内没有吊起客户端,则打开详情页面等。这个方法基本上在安卓或者IOS上都通用,不过IOS仅限IOS8及以下,IOS9以上已经不支持iframe唤起APP,不过可以通过location="schemeURL"的方式来唤起,下面我们展示以下安卓开发方面的配置:
Android清单文件中加入以下代码
<activity android:name=".DeepLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="share"
android:scheme="will" />
</intent-filter>
</activity>
**!!!!!注意:data中的host与scheme都要写上才会生效**
在Activity中接受数据:
/**
* 从deep link中获取数据
*/
private void getDataFromBrowser() {
Uri data = getIntent().getData();
try {
scheme = data.getScheme();
host = data.getHost();
params = data.getPathSegments();
String testId = params.get(0);
tv_data.setText("Scheme: " + scheme + "\n" + "host: " + host + "\n" + "params: " + testId);
} catch (Exception e) {
e.printStackTrace();
}
}
好了这样就可以实现在浏览器中打开本地app(DeepLink)了,有的同学会问,这种方式的适配性如何?由于手头机型有限,这里列举一下楼主测试过的机型与浏览器。
由于机型与精力所限,不能覆盖更多的机型了。请大家补充下哈。祭上官方文档
https://developer.android.com/training/app-indexing/deep-linking.html#adding-filters
上面的文章是通过浏览器打开客户端
后期的文章我会详细介绍native与h5的联调中所踩的坑。这里先介绍一种极其简单的方式供大家把玩。
html中加入一个超链接 <a id="J-call-app" href="will://share/testId" class="label">立即打开>></a>
public class MainActivity extends AppCompatActivity {
WebView web_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
web_main = (WebView) findViewById(R.id.web_main);
web_main.loadUrl("file:///android_asset/h5.html");
web_main.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("will://")) {
Uri uri = Uri.parse(url);
Log.e("---------scheme: ", uri.getScheme() + "host: " + uri.getHost() + "Id: " + uri.getPathSegments().get(0));
Toast.makeText(MainActivity.this, "打开新的页面", Toast.LENGTH_LONG).show();
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
}
}