如何实现应用之间的跳转(ios和安卓)

ios:

一、应用跳转原理
应用跳转到另一个应用应该是很常见的需求,比如第三方登录,微信或者支付宝支付,就需要用到应用间跳转的技术,做过的可能知道我们需要配置一个URL Schemes:
其实这个URL Schemes就是应用间的一个通讯协议,如同http协议一样。
举个栗子:"http://127.0.0.1/path?parameter=参数"
“http://”:协议类型
127.0.0.1:服务器ip地址
“ parameter =参数”:请求的参数
iOS中苹果是如何管理应用跳转的呢?其实就是UIApplication下面这个 的API
<pre>

  • (BOOL)openURL:(NSURL*)url;
    </pre>
    它的一些我们非常熟悉的用法:
    //拨打系统电话
    <pre>
    NSURL *url = [NSURL URLWithString:@"tel://10086"];
    [[UIApplication sharedApplication] openURL:url];
    </pre>
    //发送系统短信
    <pre>
    NSURL *url = [NSURL URLWithString:@"sms://1383838438"];
    [[UIApplication sharedApplication] openURL:url];
    </pre>

二、实现两个app间的跳转
创建两个示例应用,Test1和Test2,现在需要实现从Test1跳转到Test2中
1、在被跳转的TestDemo配置一个协议scheme,这里命名为test(名字可随意配置,当然最好是英文并且跟你项目相关)
targets -> info -> URL Types ->URL Scheme ->填写协议

QQ20161207-0@2x.pn注意:不需要填写成“test://”可能会导致不可用

2、在Test2中实现一个跳转方法,方法内部代码如下:
<pre>
NSURL *url = [NSURL URLWithString:@"myTest://"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
else{
NSLog(@"没有安装应用");
}
</pre>

针对iOS9.0以后,需要配置协议白名单,用过微信或支付宝支付的肯定很清楚,也都配过。
在Test2的info.plist文件中增加一个LSApplicationQueriesSchemes
字段,把它设置为数组类型,并配置需要跳转的协议名单

三、跳转到指定界面
想要跳转到指定界面,必然是上一个app告诉下一个app(被跳转的app)需要跳转到哪个界面,而如何告诉它这里便涉及到两个app的通信。我们从上面可以知道,两个app之间的跳转只需要配置一个scheme,然后通过UIApplication
调用它的对象方法openURL:
即可实现,除此之外再也没有实现任何代码了。而这之间是如何通信的呢?
答案依然是协议,请看下面步骤:

  • 1、在"myTest://"协议后面的域名加上一些字段用来标记需要跳转的界面

进入测试界面方法体如下
<pre>
NSURL *url = [NSURL URLWithString:@"myTest://test"];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}else{
NSLog(@"没有安装应用"); }
</pre>

  • 2、来到被跳转的应用Test的AppDelegate监听其代理方法
application:handleOpenURL:

//当应用程序将要被其他程序打开时,会先执行此方法,并传递url过来
iOS9.0之前用下面的方法

application:openURL:options:

//注意适配:9.0后用这个方法:
<pre>
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{

NSLog(@"url:%@",url.absoluteString);
NSLog(@"host:%@",url.host);
if ([url.host isEqualToString:@"test"])
{
NSLog(@"进入测试界面");
}
return YES;
}
</pre>

安卓:

web页面判断手机里是否安转应用的原理就是:首先试着打开手机端某个app的本地协议;如果超时就转到app下载页,下载该app。

下面说说

URL scheme 概述

URL scheme 的作用

客户端应用可以向操作系统注册一个 URL scheme,该 scheme 用于从浏览器或其他应用中启动本应用。通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如车辆详情页、订单详情页、消息通知页、促销广告页等等。也可以执行某些指定动作,如订单支付等。也可以在应用内通过 html 页来直接调用显示 app 内的某个页面。

URL scheme 的格式

客户端自定义的 URL 作为从一个应用调用另一个的基础,遵循 RFC 1808 (Relative Uniform Resource Locators) 标准。这跟我们常见的网页内容 URL 格式一样。

一个普通的 URL 分为几个部分,schemehostrelativePathquery

比如:http://www.baidu.com/s?rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709,这个URL中,scheme 为 httphost 为www.baidu.comrelativePath 为 /squery 为 rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709

一个应用中使用的 URL 例子(该 URL 会调起车辆详情页):uumobile://mobile/carDetail?car_id=123456,其中 scheme 为 uumobilehost 为mobilerelativePath 为 /carDetailquery 为 car_id=123456

Scheme定义Activity

1)在androidmanifest.xml中定义scheme

<!-- 启动页 -->
<activity
    android:name="com.qiyuan.congmingtou.activity.SplashActivity"
    android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </intent-filter>
    <!-- 要想在别的App上能成功调起App,必须添加intent过滤器 -->
    <intent-filter>
        <!-- 协议部分,随便设置 -->
        <data android:scheme="cmt" android:host="splash"/>
        <!-- 下面这几行也必须得设置 -->
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <action android:name="android.intent.action.VIEW" />
    </intent-filter>
</activity>
这样我们便定义了能够接受scheme请求的activity实例,当网页或者是android代码发送这种规则scheme的请求的时候就能够吊起SplashActivity了。

2.网页中Html代码和js代码

<!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: 'IfInstalledCongMingTou://congmingtou',
                    scheme_Adr: 'cmt://splash',
                    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>
  如果我们要用于实现对scheme的解析,然后做出相应的动作,比如请求scheme跳转登录页面,要在SplashActivity中做写相应的代码:

public class SplashActivity extends Activity{
    public Activity mContext = null;

    public void onCreate(Bundle b)
    {
        super.onCreate(b);
        mContext = this;
        Uri uri = getIntent().getData();
        if (uri != null)
        {
            List<String> pathSegments = uri.getPathSegments();
            String uriQuery = uri.getQuery();
            Intent intent            if (pathSegments != null && pathSegments.size() > 0) {
                // 解析SCHEME
                if (someif) {
                    dosomething();
                }
                else {
                    // 若解析不到SCHEME,则关闭NativeAppActivity                    finish();
                }
            } else {
                finish();
            }
        } else {
            finish();
        }
    }

}

这里简单说一下,我们可以通过Intent对象获取调用的scheme的host等信息

this.getIntent().getScheme();//获得Scheme名称  
this.getIntent().getDataString();//获得Uri全部路径 

 
 
 
 

通过服务器下发跳转路径跳转相应页面

startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("uumobile://yongche/123123123")));

 
 
 
 

这里的”uumobile://yongche/123123123”就是服务器下发的跳转路径,当我们执行startActivity的时候就会调起SpalshActivity,然后我们通过在SpalshActivity解析scheme的内容,跳转相应的页面



总结: 
android中的scheme是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面; 
通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值