如何禁止第三方软件不能安装

如何禁止第三方软件不能安装

类别

需求

索引类别

禁止静默安装install apk

问题描述

对于应用市场来说,内存大小总是不够大,所以在一定空间后(eg:小于500M后)禁止安装第三方软件。

代码关联

android/frameworks/base$ git diff
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index a505a69..1f819b1 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1081,6 +1081,8 @@ public final class Pm {
                 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
             } else if (opt.equals("-g")) {
                 installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
+            } else if (opt.equals("-c")) { 	//这步主要是为了区分对应是否是内置的强制推送安装的apk
+                installFlags |= PackageManager.INSTALL_USE_HEAD_SPACE_400M;
             } else if (opt.equals("--originating-uri")) {
                 originatingUriString = nextOptionData();
                 if (originatingUriString == null) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 433ab66..eec7a56 100755
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -421,6 +421,9 @@ public abstract class PackageManager {
     /** {@hide} */
     public static final int INSTALL_FORCE_VOLUME_UUID = 0x00000200;

+    /* {@hide}Force the use of reserved space */
+    public static final int INSTALL_USE_HEAD_SPACE_400M = 0x00000400;
+

diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index dd959ec..12a2bfd 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -147,6 +147,7 @@ import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Debug;
 import android.os.Binder;
+import android.os.StatFs;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
@@ -10116,10 +10117,38 @@ public class PackageManagerService extends IPackageManager.Stub {
                 verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
     }
+	// get sdcard free
+    public Boolean SpaceEnough() {
+       int headspace = 500;     // head 500M
+ 		Environment.setUserRequired(false);
+       StatFs emmc_sd_path = new StatFs(Environment.getExternalStorageDirectory().getPath());
+       long blockSize = emmc_sd_path.getBlockSize();
+       long availableBlocks = emmc_sd_path.getAvailableBlocks();
+       long emmc_sd_free = blockSize * availableBlocks;
+       int sd_free = new Long(emmc_sd_free/1024/1024).intValue();
+       if (sd_free < headspace)
+           return false;
+
+       return true;
+    }
+
     @Override
     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
             int installFlags, String installerPackageName, VerificationParams verificationParams,
             String packageAbiOverride, int userId) {
+       int useHeadspaceFlags = PackageManager.INSTALL_USE_HEAD_SPACE_400M | PackageManager.INSTALL_ALL_USERS;		// <-- 0x400 | 0x40
+       boolean useHeadspace_400M = "true".equals(SystemProperties.get("persist.evideo.use.headspace","false"));
+       if (installFlags == useHeadspaceFlags) {
+           installFlags = PackageManager.INSTALL_REPLACE_EXISTING | PackageManager.INSTALL_ALL_USERS ;			// <-- 0x2 | 0x04  (install -r 的命令flag)
+       } else if (useHeadspace_400M && !SpaceEnough()) {
+           try {
+                Slog.w(TAG, "data headspace less than 400M ,please release space !!!");
+                observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
+                return ;
+           } catch (RemoteException re) {
+           }
+       }
+
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);

         final int callingUid = Binder.getCallingUid();

原理:就是将所有的installFlags拦截下来,除了特定设置的标志位(0x400【INSTALL_USE_HEAD_SPACE_400M】 | 0x40 【INSTALL_ALL_USERS】)才可以安装.另外还有一个就是属性值(persist.evideo.use.headspace)设定是用来区分不需要此功能的。如果是特定的标志位那么执行(0x2 【INSTALL_REPLACE_EXISTING】| 0x40 )静默安装apk。

①Pm.java 添加解释:后续补充如何实现pm install到Pm.java的过程。

②PackageManagerService.java添加解释:installPackageAsUser()这个是静默应用安装apk的接口。

遇到的坑

由于更新了api接口导致引发的错误,添加{@hide}将其隐藏,对应编译就可以正常编译通过了。
问题二:

安装应用代码:
public Installer(Context context) {
 try {
 pm = context.getPackageManager();
Class<?>[] types = new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class};
            method = pm.getClass().getMethod("installPackage", types);
            method.invoke(pm, apkFile, observer, flag, installerPackageName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
错误日志:
12-03 09:45:42.578 7898-7913/com.evideo.kmbox.appmarket I/Installer: [BaseAppInstaller(321): Installer.java:411] - --installPath:/storage/emulated/0/market/com.elinkway.tvlive2.69cf8103806614a11da330dee1c614bd_1203987403.apk?r=714734?t=aaaa
12-03 09:45:42.579 7898-7913/com.evideo.kmbox.appmarket D/Installer: [BaseAppInstaller(321): Installer.java:423] - install app with flag 2: com.elinkway.tvlive2
12-03 09:45:42.598 3050-4650/system_process E/Environment: Path requests must specify a user by using UserEnvironment
    java.lang.Throwable
        at android.os.Environment.throwIfUserRequired(Environment.java:760)
        at android.os.Environment.getExternalStorageDirectory(Environment.java:339)
        at com.android.server.pm.PackageManagerService.SpaceEnough(PackageManagerService.java:10122)
        at com.android.server.pm.PackageManagerService.installPackageAsUser(PackageManagerService.java:10139)
        at com.android.server.pm.PackageManagerService.installPackage(PackageManagerService.java:10116)
        at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:977)
        at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:2642)
        at android.os.Binder.execTransact(Binder.java:453)
12-03 09:45:51.650 8177-8177/? W/dex2oat: Compilation of void com.baidu.mobads.production.p.onAdClicked(com.baidu.mobads.interfaces.IXAdContainer, com.baidu.mobads.interfaces.IXAdInstanceInfo, java.lang.Boolean, java.util.HashMap) took 116.046ms
12-03 09:46:01.744 3050-3096/system_process W/PackageManager: Unknown permission android.permission.BROADCAST_PACKAGE_INSTALL in package com.elinkway.tvlive2
12-03 09:46:01.890 3050-3096/system_process W/Settings: Setting install_non_market_apps has moved from android.provider.Settings.Global to android.provider.Settings.Secure, returning read-only value.

解决方法: 添加Environment.setUserRequired(false); 不调用这个方法;

    /** {@hide} */
    public static void setUserRequired(boolean userRequired) {
        sUserRequired = userRequired;
    }

    private static void throwIfUserRequired() {
        if (sUserRequired) {
            Log.wtf(TAG, "Path requests must specify a user by using UserEnvironment",
                    new Throwable());
        }
    }
}
## 改进建议

工作记录…



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值