Android PMS之禁止某个应用安装

在Android系统定制开发中,我不知道该功能有没有用在商用的产品中,最近在看PMS的源码,PMS里面包含了应用的安装、卸载等功能,那我们能不能在PMS里面去限制某个应用的安装或者卸载呢?答案是当然能,因为整个系统的应用安装都要走PMS,我们只需要在PMS里面拦截安装,即可实现此功能,下面上代码。
PMS代码片段:

  /* Called when a downloaded package installation has been confirmed by the user */
    public void installPackage(
            final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
        installPackage(packageURI, observer, flags, null);
    }

    /* Called when a downloaded package installation has been confirmed by the user */
    public void installPackage(
            final Uri packageURI, final IPackageInstallObserver observer, final int flags,
            final String installerPackageName) {
        installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
                null, null);
    }

    @Override
    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
            int flags, String installerPackageName, Uri verificationURI,
            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
        VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
                VerificationParams.NO_UID, manifestDigest);
        installPackageWithVerificationAndEncryption(packageURI, observer, flags,
                installerPackageName, verificationParams, encryptionParams);
    }

    public void installPackageWithVerificationAndEncryption(Uri packageURI,
            IPackageInstallObserver observer, int flags, String installerPackageName,
            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
                null);

        final int uid = Binder.getCallingUid();
        if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
            try {
                observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
            } catch (RemoteException re) {
            }
            return;
        }
		

        UserHandle user;
        if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
            user = UserHandle.ALL;
        } else {
            user = new UserHandle(UserHandle.getUserId(uid));
        }

        final int filteredFlags;

        if (uid == Process.SHELL_UID || uid == 0) {
            if (DEBUG_INSTALL) {
                Slog.v(TAG, "Install from ADB");
            }
            filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
        } else {
            filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
        }

        verificationParams.setInstallerUid(uid);
		

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
                verificationParams, encryptionParams, user);
        mHandler.sendMessage(msg);
    }

我们通过阅读代码可以知道,应用安装过程一定会经过installPackageWithVerificationAndEncryption这个函数方法,即上面列出的方法,在此处我们可以拦截安装,代码如下:

 public void installPackageWithVerificationAndEncryption(Uri packageURI,
            IPackageInstallObserver observer, int flags, String installerPackageName,
            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
                null);

        final int uid = Binder.getCallingUid();
        if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
            try {
                observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
            } catch (RemoteException re) {
            }
            return;
        }
		

        UserHandle user;
        if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
            user = UserHandle.ALL;
        } else {
            user = new UserHandle(UserHandle.getUserId(uid));
        }

        final int filteredFlags;

        if (uid == Process.SHELL_UID || uid == 0) {
            if (DEBUG_INSTALL) {
                Slog.v(TAG, "Install from ADB");
            }
            filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
        } else {
            filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
        }

        verificationParams.setInstallerUid(uid);
		//start add 20230724  by liu
		try{
			if(packageURI!=null){
				Slog.v("liu-install", "apk url   "+packageURI.getPath());
				String pail=getPackageInfoLite(packageURI.getPath());
				if(pail!=null){
					Slog.v("liu-install", "Install   "+pail);
					if(pail.contains("com.dianshijia.newlive")){
						Slog.v("liu-install", "not Install   "+pail);
						return;
					}
				}
			}
			
			}catch(RemoteException e){
			
			}
		//end add 20230724  by liu

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
                verificationParams, encryptionParams, user);
        mHandler.sendMessage(msg);
    }
	/**
	*start add 20230724  by liu
	*/
	private String getPackageInfoLite(String packageFilePath)  throws RemoteException{
			//file:///storage/emulated/0/dianshijia.apk 
			//
			PackageParser.PackageLite pkg = PackageParser.parsePackageLite(packageFilePath, 0);
            if (pkg == null) {
               
                /*final File apkFile = new File(packagePath);
                if (!apkFile.exists()) {
                    ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
                } else {
                    ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
                }*/
				return null;
                
            }
			return pkg.packageName;
					
		}

加上上面拦截代码,即可实现应用安装限制,adb 安装或者系统安装都可,以上可能还有需要完善的地方,欢迎留言!

QQ交流:3151365988
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值