首页 > 其他分享 >Android Launcher apk 授信安装

Android Launcher apk 授信安装

时间:2023-07-05 11:36:16浏览次数:37  
标签:pkgName Log PACKAGE Launcher apk TAG intent VERIFICATION Android

对安装的apk进行校验,除了系统应用市场中下载的,其它渠道的apk都进行安装拦截,并且弹框提示。

首先需要把验证的证书保存在数据库本地,后面需要用到

然后注册系统广播,用于接收 apk 安装时的监听,这个广播由系统发出

新装时的

action ‘android.intent.action.PACKAGE_ADDED

替换时的 action

android.intent.action.PACKAGE_REMOVED

android.intent.action.PACKAGE_ADDED

android.intent.action.PACKAGE_REPLACED

删除时的 action

android.intent.action.PACKAGE_REMOVED

android.intent.action.PACKAGE_FULLY_REMOVED

 

<receiver android:name="com.ecarx.verifier.main.VerifyReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION" />
                <data android:mimeType="application/vnd.android.package-archive" />
            </intent-filter>
</receiver>

安卓 4.0 新增了 verifyPendingInstall,用于监听包管理,验证时发送广播

验证通过 PackageManager.VERIFICATION_ALLOW 跟验证失败 PackageManager.VERIFICATION_REJECT

在注册一个服务,用于 apk 安装接收到广播后的校验处理

<service android:name="com.ecarx.verifier.main.VerifyService"
            android:exported="true">
            <intent-filter>
                <action android:name="ecarx.install.verify" />
            </intent-filter>
</service>

接下来就是监听跟验证,首先在安装apk时会收到广播,然后可以拿到信息开启服务验证

public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "onReceive: start");

        String action = intent.getAction();
        if (Intent.ACTION_PACKAGE_NEEDS_VERIFICATION.equals(action)) {
            Log.e(TAG, "onReceive: " + "ACTION_PACKAGE_NEEDS_VERIFICATION");

            Intent verification = new Intent();
            verification.setAction(VerifyConstant.VERIFY_SERVICE_ACTION);
            verification.setPackage(VerifyConstant.VERIFY_SERVICE_PACKAGE_NAME);

            Bundle sExtras = new Bundle(intent.getExtras());
            sExtras.putInt(VerifyManager.Cmd.CMD_KEY, VerifyManager.Cmd.CMD_VERIFY);
            String path = intent.getData().getPath();
            Log.e(TAG, "path: " + path);
            if (!path.endsWith(VerifyConstant.INSTALL_FILE_SUFFIX)) {
                path = path + "/base.apk";
            }
            sExtras.putString("PACKAGE_PATH", path);
            verification.putExtras(sExtras);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                AppPlugins.appCtx().startForegroundService(verification);
            } else {
                AppPlugins.appCtx().startService(verification);
            }
            return;
        }
        if (Intent.ACTION_PACKAGE_VERIFIED.equals(action)) {
            Log.d(TAG, "onReceive: " + "ACTION_PACKAGE_VERIFIED");
            return;
        }
    }

服务 VerifyService extends IntentService

系统校验时间默认为10秒超时,如果下载的是大型游戏可能会anr,所以需要默认改下超时时间

并且在服务中需要弹框处理,这两个操作放到 onCreate 中

@Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
        Settings.Global.putLong(getContentResolver(), PACKAGE_VERIFIER_TIMEOUT, MAX_VERIFICATION_TIMEOUT);
        VerifyUtils.setVerifyInstallListener(isAllow -> {
            Log.d(TAG, "setVerifyInstallListener isAllow : " + isAllow);
            if (!isAllow) {
                ArchTaskExecutor.getInstance().postToMainThread(this::showInstallTipDialog);
            }
        });
    }

然后处理具体的验证逻辑

@Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if (intent == null) return;
        if (intent.getExtras() == null) return;

        int cmd = intent.getIntExtra(VerifyManager.Cmd.CMD_KEY, 0);
        switch (cmd) {
            case VerifyManager.Cmd.CMD_VERIFY: {    
                Bundle extras = intent.getExtras();
                int id = extras.getInt(PackageManager.EXTRA_VERIFICATION_ID);
                String pkgName = extras.getString(EXTRA_VERIFICATION_PACKAGE_NAME);
                String packagePath = extras.getString("PACKAGE_PATH", null);
                String installerPkg = extras.getString(EXTAR_VERIFICATION_INSTALLER_PKG);

                PackageManager pm = this.getPackageManager();
                boolean isSystemApp = VerifyUtils.isSystemApp(pkgName);
                Log.e(TAG, "isSystemApp " + isSystemApp);
                if (isSystemApp) {
                    pm.verifyPendingInstall(id, PackageManager.VERIFICATION_ALLOW);
                    if (DEBUG) {
                        Log.e(TAG, pkgName + " : System App ALLOW");
                    }
                    return;
                }

                boolean isOverlayApp = VerifyUtils.isOverlayApp(packagePath);
                Log.e(TAG, "isOverlayApp " + isOverlayApp);
                if (isOverlayApp) {
                    pm.verifyPendingInstall(id, PackageManager.VERIFICATION_ALLOW);
                    if (DEBUG) {
                        Log.e(TAG, pkgName + " : Overlay App ALLOW");
                    }
                    return;
                }

                Log.e(TAG, "installerPkg " + installerPkg);
                if (DEVICESERVICE_PACKAGE_NAME.equals(installerPkg) && VerifyUtils.isSystemPackage(DEVICESERVICE_PACKAGE_NAME)) {
                    pm.verifyPendingInstall(id, PackageManager.VERIFICATION_ALLOW);
                    if (DEBUG) {
                        Log.e(TAG, pkgName + " : Debugtool install App ALLOW");
                    }
                    return;
                }
                String sha1 = getMd5VerifyResult(packagePath);

                boolean isLegal = VerifyUtils.isLegal(sha1, pkgName);
                Log.e(TAG, "isLegal " + isLegal);
                if (isLegal) {
                    pm.verifyPendingInstall(id, PackageManager.VERIFICATION_ALLOW);
                    if (DEBUG) {
                        Log.e(TAG, pkgName + " : Legal App ALLOW");
                    }
                    return;
                }
                VerifyUtils.verifyOnlineSign(id, packagePath, pkgName, sha1);
                return;
            }
        }
        }
}        

具体验证方法

    public static void verifyOnlineResp(int id, String localSha1, String pkgName, SignatureResp signatureResp) {
        String signText = signatureResp.getSign();
        int signType = signatureResp.getSignType();
        String sha1 = signatureResp.getApkSign();
        String content = generateContent(signType, pkgName, sha1);

        boolean verifyResult = VerifyUtils.verifySign(content, signText, publicKeyStr);
        if (verifyResult) {
            SignEntity signEntity = new SignEntity(pkgName, sha1, content, signType, signText);
            AppDatabase.getInstance().signDao().insertSignSync(signEntity);
        }
        reportVerifyResult(id, pkgName, verifyResult);

    }

    public static void reportVerifyResult(int id, String pkgName, boolean isAllow) {
        int resultCode = isAllow ? PackageManager.VERIFICATION_ALLOW : PackageManager.VERIFICATION_REJECT;
        String resultStr = isAllow ? "Allow" : "Reject";
        AppPlugins.appCtx().getPackageManager().verifyPendingInstall(id, resultCode);
        if (listener != null) {
            listener.verifyResult(isAllow);
        }
        Log.e(TAG, pkgName + " : " + resultStr);
    }

 

标签:pkgName,Log,PACKAGE,Launcher,apk,TAG,intent,VERIFICATION,Android
From: https://www.cnblogs.com/LiuZhen/p/17526295.html

相关文章

  • android studio下载地址
    AndroidStudio3.0下载地址——高速下载https://www.androiddevtools.cn/ 谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快。下载地址:https://developer.android.google.cn/studio/archive.html选择显示全部即可看到下载地址,这里给出来了。Wi......
  • MAUI Blazor Android 输入框软键盘遮挡问题2.0
    前言关于MAUIBlazorAndroid输入框软键盘遮挡问题,之前的文章已经有了答案,MAUIBlazorAndroid输入框软键盘遮挡问题但是这个方案一直存在一点小的瑕疵在小窗模式下,界面的高度始终不正确所以本篇文章重点解决这个问题特别感谢这篇文章AndroidwebView输入框软键盘遮挡问题......
  • Android BottomNavigation底部导航栏使用
    原文地址:AndroidBottomNavigation底部导航栏使用-Stars-One的杂货小窝基本使用本文侧重点记录一些特殊的样式设置,所以基本使用这里就简单概述一下,详细图文可以去找其他人的博文1.创建对应的menu菜单文件2.xml布局引用menu菜单3.启动Activity预览效果可以使用setOnIte......
  • android Toast大全(五种情形)建立属于你自己的Toast
    Toast大全(五种情形)建立属于你自己的Toast Toast用于向用户显示一些帮助/提示。下面我做了5中效果,来说明Toast的强大,定义一个属于你自己的Toast。 1.默认效果 Java代码  1.Toast.makeText(getApplicationContext(),"默认Toast样式",Toast.LENGTH_......
  • [Unity3D]Unity+Android交互教程——让手机"动"起来
    更多教程请访问:http://dingxiaowei.cn/ 想要用Unity实现一个二维码扫描的功能,然后网上找插件,找到一个貌似叫EasyCodeScanner,但下载下来用用,真不好使,一导入运行就报错,调好错了再运行发现点按钮没反应,反复试了几遍发现还是没反应,没办法看源码,结果发现只实现了IOS部分,没有Android部......
  • android tts语音使用的一些资料(转)
     TextToSpeech简称TTS,是Android1.6版本中比较首要的新功能。将所指定的文本转成不同语言音频输出。它可以方便的嵌入到游戏或者使用程序中,增强用户体验。   在讲解TTSAPI和将这项功能使用到你的实际项目中的要领之前,先对这套TTS引擎有个初步的明白。 对TTS资源的大......
  • android 音标的抓取 腾讯在线词典API
       DICT.CN的webAPI已经close了,本想好,调用下接口把读音给抓下来。幸好,网上还是有好多的资源可以用的。昨天回去的时候,做了一个QQ的word抓音标的例子,还是大公司好,虽然非常的BS腾讯这狗抄袭人家的创意甚至是产品。 下面是几个开发的API测试了了是用于用的,但是你的程序中,文件......
  • android 基于ListView和CheckBox实现多选和全选记录的功能(转)
    [原]基于ListView和CheckBox实现多选和全选记录的功能应用开发中经常会有从数据库中读取数据显示,然后选中多条、全部记录并且删除的需求。在做定制系统联系人的时候也遇到这样的需求,下面写个简单的通过ListView和CheckBox实现多选、全选的例子。下面是具体的代码,有问题请留言。代......
  • Android 4.0 SDK的离线方式安装
     昨天看新闻得知新版本的android系统发布了,android4.0是人们期盼多时的版本了。作为一个IT技术人员,迫不及待地就奔向了http://developer.android.com去看看有没有新的SDK公布出来,当时是上午,没见到有更新,心想一定是若干天后才会发布。没想到同事下午告诉我,新版的SDK已经发布了。......
  • Android 原生混合flutte运行:Could not resolve io.flutter。
    Android原生项目混合开发flutter,在运行新项目的时候报错。>Couldnotresolveio.flutter:flutter_embedding_debug:1.0.0-2a3401c9bbb5a9a9aec74d4f735d18a9dd3ebf2d. 解决方案添加   url"https://storage.flutter-io.cn/download.flutter.io"repositories{......