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

Android Launcher apk 授信安装

时间:2023-09-19 20:00:48浏览次数:48  
标签:pkgName Log PACKAGE Launcher apk TAG intent VERIFICATION Android

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

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

Android Launcher apk 授信安装_Text

然后注册系统广播,用于接收 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,用于监听包管理,验证时发送广播

Android Launcher apk 授信安装_Text_02

验证通过 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://blog.51cto.com/u_16175630/7528465

相关文章

  • Linux: Android系统
    Android系统架构Android是谷歌开发的一款基于Linux内核的操作系统。系统架构分为五层,从下到上依次是Linux内核层、硬件抽象层、系统运行库层、应用框架层和应用层。通俗点从下往上依次是:Linuxkernel层,很大一部分内容是驱动程序HAL层,对下封装驱动硬件操作,对上向App提......
  • 探索相芯Animoji:与动漫滤镜一起开启独特的虚拟表情世界(Android)
    相芯SDK中的Animoji特效通过结合人像分割、面部识别和虚拟角色技术,为用户提供了丰富多样的动态特效体验。使用任意手机摄像头,即可实时驱动Xmoji。支持含面部、舌头、眼球在内的56种基础表情,可融合成千上万表情形态,让虚拟卡通形象实时跟随人脸做出活灵活现的表情。相芯SDK还提供了丰......
  • HBuilder打包vue2.0项目生成的APK空白(已解决)
    1、config下面的index.js中bulid模块导出的路径,因为index.html里边的内容都是通过script标签引入的,而路径不对,打开肯定是空白的。先看一下默认的路径。build:{//Templateforindex.html//Paths需要修改的是这里的路径index:path.resolve(__dirname,'........
  • 【gradle.kts maven 添加】【android】
    org.gradle.api.InvalidUserCodeException:Buildwasconfiguredtoprefersettingsrepositoriesoverprojectrepositoriesbutrepository'maven'wasaddedbybuildfile'app/build.gradle.kts'在setting里加  dependencyResolutionMa......
  • 短视频app源码,Android TextView文字,删除线以及下划线
    短视频app源码,AndroidTextView文字,删除线以及下划线1、删除线 TextViewtextview=(TextView)view.findViewById(R.id.textviewk);textview.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);​2、下划线 TextViewtextview=(TextView)view.findViewById(R.id.textvi......
  • android短视频开发,点击两次实现不同点击效果的实现方式
    android短视频开发,点击两次实现不同点击效果的实现方式布局:<RelativeLayout    android:id="@+id/rl_picture_group"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:visibility="gone"......
  • 【Android studio】【Gradle】dependencies配置参数细解及异常解决
    依赖项配置implementationGradle会将依赖项添加到编译类路径,并将依赖项打包到构建输出。不过,当您的模块配置implementation依赖项时,会让Gradle了解您不希望该模块在编译时将该依赖项泄露给其他模块。也就是说,其他模块只有在运行时才能使用该依赖项。使用此依赖项配置代替api......
  • 【Android Studio】布局验证 Layout Validation
    官方效果如下:布局验证是一款可视化工具,用于同时预览不同设备上及采用不同配置的布局,有助于您察觉布局错误并打造无障碍水平更高的应用。色盲为了方便色盲用户使用您的应用,请通过常见色盲类型的模拟验证布局:亲测效果如下:打开位置如下图:更多我的开源地址,欢迎star和fork。拿来即用,你......
  • 【Android studio】使用 Database Inspector 调试数据库【MyAndroid】
    在AndroidStudio4.1及更高版本中,您可以利用DatabaseInspector在应用运行时检查、查询和修改应用的数据库。这对于数据库调试尤为有用。DatabaseInspector可处理普通的SQLite数据库以及在SQLite的基础上构建的库(例如Room)。注意:DatabaseInspector仅可与API级别26......
  • 【MyAndroid】轮播图和指示器
    轮播图ImageViewiv1=(ImageView)LayoutInflater.from(this).inflate(R.layout.banner_item,bannerViewPager,false);ImageViewiv2=(ImageView)LayoutInflater.from(this).inflate(R.layout.banner_item,bannerViewPager,false);ImageViewiv3=(Image......