Scheme跳转协议

Scheme 是一种页面内跳转协议

一、应用场景有三种:

1.服务器可以定制化的跳转到app的某一个页面(体现在服务器推送一条消息,我们跳到广告页/账单页等。)

2.h5页面可以定制化跳转到app的某一个页面(体现在h5浏览器中增加一个按钮去直接去app的某一个页面)

3.app内可以跳转到另一个app中的某一个页面(体现在跳转到应用市场下载/更新/评价,跳转到支付宝支付等……)

当一个应用想打开另一个应用时,另一个应用必须配置Scheme协议。这样程序才能根据协议找到想要打开的应用,那么如果存在两个应用的Scheme协议相同怎么办?这个时候系统会响应最先安装的app,而后安装的会被系统忽略。

二、Scheme协议的原理是什么?

其实就是约定一个协议,让其他应用可以根据协议跳转到你的应用里。

三、Scheme协议的格式是什么?

Uri.parse("bs://test:8080/abc/cbd?name=333&value=222");

可以类似的理解为一个http的地址。 

bs: 就是Scheme的协议名称,可以随便定义,类似于http

test:代表Scheme协议的作用域

8080:代表Scheme协议的端口号

/abc/cbd :代表制定的页面(路径)

name =333&value=222 :表示传递的参数

四、Scheme协议的具体使用

首先我们如果想让别的app可以跳转到我们的app就需要定义Scheme协议


    

    
    
    
    


上面具体就不做解释了,只是固定的action/category不要忘了添加,否则就无法跳转到我们的app

调用分两种,第一种是app内调用,第二种是h5调用

1.app内调用,可以根据下方工具了解

public class PackageUtil {

    /**
     * 通过包名
     *
     * 判断 app是否安装
     *
     * @param mContext
     * @param packageName
     * @return
     */
    public static boolean isInstallPackage(Context mContext, String packageName) {
        List packageInfos = mContext.getPackageManager().getInstalledPackages(0);
        List myPackageName = new ArrayList<>();
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                myPackageName.add(packageInfos.get(i).packageName);
            }
            return myPackageName.contains(packageName);
        }
        return false;
    }

    /**
     * 根据 scheme协议
     *
     * 判断是否安装了某个应用
     *
     * @param mContext
     * @param schemeUri
     * @return
     */
    public static boolean isInstallPackageUserScheme(Context mContext, String schemeUri) {
        Uri uri = Uri.parse(schemeUri);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        ComponentName componentName = intent.resolveActivity(mContext.getPackageManager());
        return componentName != null;
    }

    /**
     * 跳转到制定的app中的某个页面
     *
     * 传人任何一个app的scheme地址就可以进行跳转
     *
     * @param mContext
     * @param schemeString
     */
    public static void goToApp(Context mContext, String schemeString) {
        try {
            Uri uri = Uri.parse(schemeString);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            mContext.startActivity(intent);
        } catch (ActivityNotFoundException e) {

        }

    }

    /**
     * 跳到应用市场下载应用/给自己的应用打分/跳转到应用市场更新应用
     *
     * 这个方法支持应用宝/360/小米/豌豆荚等主流市场,如果由多个弹窗,则会弹出一个选择框
     *
     * @param mContext
     * @param packageName
     */
    public static void goToMarket(Context mContext, String packageName) {
        Uri uri = Uri.parse("market://details?id=" + packageName);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        try {
            mContext.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 为了解决小米手机默认跳转小米应用商店,
     *
     * 小米手机跳转应用宝
     *
     * @param context
     * @param packageName
     */
    public static void goToMarketXiaoMi(Context context, String packageName) {
        Uri uri = Uri.parse("market://details?id=" + packageName);
        Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
        try {
            goToMarket.setClassName("com.tencent.android.qqdownloader", "com.tencent.pangu.link.LinkProxyActivity");
            context.startActivity(goToMarket);
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 三星手机跳转
     *
     * @param context
     * @param packageName
     */
    public static void goToSamsungappsMarket(Context context, String packageName) {
        Uri uri = Uri.parse("http://www.samsungapps.com/appquery/appDetail.as?appId=" + packageName);
        Intent goToMarket = new Intent();
        goToMarket.setClassName("com.sec.android.app.samsungapps", "com.sec.android.app.samsungapps.Main");
        goToMarket.setData(uri);
        try {
            context.startActivity(goToMarket);
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        }
    }

    
}

这个工具类提供了 判断一个app是否安装/跳转到一个app的某一个页面 并且提供了有些手机默认跳转到本机自带的应用市场的解决方法。

调用时,只需要传入这个app指定页面的Scheme协议就行。

2.h5调用就只需要一句话

打开app的页面

我们可以动态的在代码中获得scheme中的内容。

/**
 * 在代码中动态的获取协议内容
 */
public void getScheme() {
    Uri uri = getIntent().getData();
    if (uri != null) {
        String schemeUri = uri.toString();
        System.out.println("schemeUri" + schemeUri);

        String scheme = uri.getScheme();
        System.out.println("scheme" + scheme);

        String host = uri.getHost();
        System.out.println("host" + host);

        int port = uri.getPort();
        System.out.println("port" + port);

        String path = uri.getPath();
        System.out.println("path" + path);

        String query = uri.getQuery();
        System.out.println("query" + query);

        // 获取制定参数
        String queryData = uri.getQueryParameter("name");
        System.out.println("queryData" + queryData);


    }
}

对于Scheme协议,我们可以灵活运用在应用中,特别在h5于app交互时,灵活的省去了h5调用java的方法。

感谢阅读 !

参考文章:

Android应用如何跳转到应用市场详情页面

https://www.jianshu.com/p/2165acb5d1eb

App之间的交互原理原来这么简单啊,涨知识了

http://www.sohu.com/a/210737771_644543

Android产品研发(十一)-->应用内跳转Scheme协议

https://blog.csdn.net/qq_23547831/article/details/51685310

你可能感兴趣的:(学习)