安卓的deepLink实现方式

最近碰到了一个新的需求,用户在浏览器中打开分享出去的内容,如果该用户设备上有我们的客户端则打开客户端并且定位到当前文章,如果没有的话则进行下载。调研过程中遇到了不少的坑,这里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">立即打开&gt;&gt;</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:必须*/
                    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清单文件中加入以下代码
 <!-- 一定要在清单文件中加入下面的intent filter !!!!!!!-->
        <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都要写上才会生效**
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
在Activity中接受数据:
    /**
     * 从deep link中获取数据
     */
    private void getDataFromBrowser() {
        Uri data = getIntent().getData();
        try {
            scheme = data.getScheme(); // "will"
            host = data.getHost(); // "share"
            params = data.getPathSegments();
            String testId = params.get(0); // "uuid"
            tv_data.setText("Scheme: " + scheme + "\n" + "host: " + host + "\n" + "params: " + testId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

好了这样就可以实现在浏览器中打开本地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">立即打开&gt;&gt;</a>
 
 
  • 1
  • 1
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; //返回true,代表要拦截这个url
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
        });
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值