美文网首页小技巧Android开发探索安卓开发博客
Android APP打开另一个APP完整逻辑实现

Android APP打开另一个APP完整逻辑实现

作者: 天一方蓝 | 来源:发表于2018-05-10 11:24 被阅读1124次

    本文出自:https://blog.csdn.net/DT235201314/article/details/80255143

    一丶概述

    前段时间配合开发,完成了一个APP拉起另一个APP的需求,负责接收数据跨登录部分。当然整个实现思路挺感兴趣就了解一下。先说说需求拉起另一个APP是为了方便统一使用管理,有些公司APP较多,部分人只需要用到部分APP,需要用到时就下载。市面上比较流行的解决办法,第一个就是现在说的新开发一个管理型APP,其他APP需要时再下载,运用时拉起,另一个就是插件化,直接将多个APP合成一个APP,这个感兴趣也可以了解一下。

    二丶效果图

    image image

    三丶需求分析

    1.A点击拉起B;

    2.如果B没安装,下载安装;

    3.如果B已安转,未在后台运行点击打开B,传值账号密码,做跨登录;

    4.如果B已安装,且正在后台运行,A打开B直接显示在后台运行的页面;

    简版流程图:

    image

    四丶原理与实现

    1.先说A拉起B可实现的几种方法

    (1)包名,特定Activity名拉起

    Intent intent = new Intent(Intent.ACTION_MAIN);
    /**知道要跳转应用的包命与目标Activity*/
    ComponentName componentName = new ComponentName("kuyu.com.xxxx", "kuyu.com.xxxx.xxx.login.WelcomeActivity");
    intent.setComponent(componentName);
    intent.putExtra("", "");//这里Intent传值
    startActivity(intent);
    

    B应用需要在manifest文件对应Activity添加

    android:exported="true"
    

    (2)包名拉起(这里就是进去启动页)

    Intent intent = getPackageManager().getLaunchIntentForPackage("kuyu.com.xxxx");
    if (intent != null) {
        intent.putExtra("type", "110");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
    

    (3)url拉起

    Intent intent = new Intent();
    intent.setData(Uri.parse("csd://pull.csd.demo/cyn?type=110"));
    intent.putExtra("", "");//这里Intent当然也可传递参数,但是一般情况下都会放到上面的URL中进行传递
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    

    B应用manifest文件需配置(注意:在原有intent-filter下方另外添加,不是在原先里面,两个同时存在)

    <intent-filter>
        <data
            android:host="pull.csd.demo"
            android:path="/cyn"
            android:scheme="csd" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
    

    优点:不暴露包命 缺点:host path schemeA应用和B应用得规定死

    2.判断B应用是否安装

    /**
     * 检查包是否存在
     *
     * @param packname
     * @return
     */
    private boolean checkPackInfo(String packname) {
        PackageInfo packageInfo = null;
        try {
            packageInfo = getPackageManager().getPackageInfo(packname, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return packageInfo != null;
    }
    

    3.判断B应用是否在后台运行并直接打开

    public static Intent getAppOpenIntentByPackageName(Context context,String packageName){
        //Activity完整名
        String mainAct = null;
        //根据包名寻找
        PackageManager pkgMag = context.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED|Intent.FLAG_ACTIVITY_NEW_TASK);
    
        List<ResolveInfo> list = pkgMag.queryIntentActivities(intent,
                PackageManager.GET_ACTIVITIES);
        for (int i = 0; i < list.size(); i++) {
            ResolveInfo info = list.get(i);
            if (info.activityInfo.packageName.equals(packageName)) {
                mainAct = info.activityInfo.name;
                break;
            }
        }
        if (TextUtils.isEmpty(mainAct)) {
            return null;
        }
        intent.setComponent(new ComponentName(packageName, mainAct));
        return intent;
    }
    
    public static Context getPackageContext(Context context, String packageName) {
        Context pkgContext = null;
        if (context.getPackageName().equals(packageName)) {
            pkgContext = context;
        } else {
            // 创建第三方应用的上下文环境
            try {
                pkgContext = context.createPackageContext(packageName,
                        Context.CONTEXT_IGNORE_SECURITY
                                | Context.CONTEXT_INCLUDE_CODE);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return pkgContext;
    }
    
    public static boolean openPackage(Context context, String packageName) {
        Context pkgContext = getPackageContext(context, packageName);
        Intent intent = getAppOpenIntentByPackageName(context, packageName);
        if (pkgContext != null && intent != null) {
            pkgContext.startActivity(intent);
            return true;
        }
        return false;
    }
    
    if (checkPackInfo("kuyu.com.xxxxx")) {
    openPackage(this,"kuyu.com.xxxxx");
    } else {
        Toast.makeText(this, "没有安装" + "",Toast.LENGTH_LONG).show();
        //TODO  下载操作
    }
    

    这里运用的是模拟点击图标启动,不会出现程序多开,和栈顶Activity重复或者顺序错乱的问题。

    当然Activity的LaunchMode最好设为“singletop”

    4.B应用接受传值跨登录操作

    一般启动页有几种操作

    (1)定时直接跳转登录页面

    这个就简单了,直接在handle发送跳转做判断接收intent操作就可以了

    例:

    if(getIntent().hasExtra("xxxx")){
        otherOpen();
    }else {
        mHandler.removeMessages(0);
        mHandler.sendEmptyMessageDelayed(0, 3000);
    }
    

    (2)做了用户信息保存,跳过登录的,这个时候就通过handle的消息判断,做出相应操作

    例:

    /**
     * 跳去首页/登录页面
     */
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.arg1) {
                case 1009:
                    goToActivity(MainActivity.class);
                    WelcomeActivity.this.finish();
                    break;
                case 1010:
                    gotoLogin(handler1, runnable);
                    break;
            }
        }
    };
    

    五丶参考文章

    Android从一个APP跳转到另一个APP的主界面或某页面,并传递数据

    Android-跳转第三方app重复启动问题

    通过 PackageManager 获得你想要的 App 信息

    如果文章对你有帮助,欢迎点赞关注

    源码下载:

    https://github.com/JinBoy23520/CoderToDeveloperByTCLer

    写在最后微信扫码提问

    image

    相关文章

      网友评论

      • 才兄说:有一定基础后,配合代码模板,或者源码库,开发效率简直飞起来。可以参考这篇文章一起做个工具库
      • ead5e96b1720:这篇喜欢就多点了
        天一方蓝:我也很惊讶
      • 65ffec668b05:文章很有条理了

      本文标题:Android APP打开另一个APP完整逻辑实现

      本文链接:https://www.haomeiwen.com/subject/kkrzrftx.html