Android应用层PackageManager的使用

Android应用层PackageManager的使用

一、PackageManager 的使用
1.1、安装和卸载应用
1.2、查询permission相关的信息
应用申请的权限都会在PackageInfo 里面包含有
1.3、查询Application相关信息(application activity receiver service provider)
1.4、查询已安装的应用
1.5、增加或者删除permissin
1.6、清除用户数据、缓存、代码段等
1.7、android应用的状态及设置方法

二、PackageManager 对象的获取方式 
PackageManager mPm = Context.getPackageManager();

三、安装应用和卸载应用
3.1 安装应用
静默安装

PackageInstallObserver observer = new PackageInstallObserver();

class PackageInstallObserver extends IPackageInstallObserver.Stub {
        public void packageInstalled(String packageName, int returnCode) {
            Message msg = null;
            switch (returnCode) {
                case PackageManager.INSTALL_SUCCEEDED:
                    msg = mHandler.obtainMessage(InstallConstant.MessageCommand.INSTALL_COMPLETE);
                    break;
                case PackageManager.INSTALL_FAILED_ALREADY_EXISTS:   //-1
                case PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER:  //-13
                case PackageManager.INSTALL_FAILED_CONTAINER_ERROR:   //-18
                case PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE:  //-16
                case PackageManager.INSTALL_FAILED_DEXOPT:   //-11
                case PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE:  //-5
                case PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE:  //-4
                case PackageManager.INSTALL_FAILED_INTERNAL_ERROR:   //-110
                case PackageManager.INSTALL_FAILED_INVALID_APK:   //-2
                case PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION:   //-19
                case PackageManager.INSTALL_FAILED_INVALID_URI:   //-3
                case PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE:   //-20
                case PackageManager.INSTALL_FAILED_MISSING_FEATURE:  //-17
                case PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY:  //-9
                case PackageManager.INSTALL_FAILED_NEWER_SDK:   //-14
                case PackageManager.INSTALL_FAILED_NO_SHARED_USER:   //-6
                case PackageManager.INSTALL_FAILED_OLDER_SDK:   //-12
                case PackageManager.INSTALL_FAILED_PACKAGE_CHANGED:  //-23
                case PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE:  //-10
                case PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE:  //-8
                case PackageManager.INSTALL_FAILED_TEST_ONLY:  //-15
                case PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE:  //-7
                case PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE:  //-22
                case PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT:   //-21
                case PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST:    //-101
                case PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME:   //-106
                case PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID:   //-107
                case PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING:  //-105
                case PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES:  //-104
                case PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY:  //-109
                case PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED:  //-108
                case PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES:   //-103
                case PackageManager.INSTALL_PARSE_FAILED_NOT_APK:     //-100
                case PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION:   //-102
                default:
                    msg = mHandler.obtainMessage(InstallConstant.MessageCommand.DLG_INSTALL_ERROR);
                    break;
            }
        }


Uri uri = Uri.fromFile(new File(mAppInfo.getFileName()));
pm.installPackage(uri, observer,
                    mAppInfo.installFlag, mAppInfo.getPackageName());
installPackage


调用PackageInstall 安装 

通过 Intent 机制,调出系统安装应用,重新安装应用的话,会保留原应用的数据
String fileName = Environment.getExternalStorageDirectory() + apkName ;
Uri uri = Uri.fromFile( new File(fileName));
Intent intent = new Intent(Intent. ACTION_VIEW );
intent.setDataAndType(Uri, application/vnd.android.package-archive" );
startActivity(intent);
PackageInstall.apk 安装

 

 

3.2 卸载应用

mContext.getPackageManager().deletePackage(mAppInfo.packageName,
     new IPackageDeleteObserver.Stub() {
      @Override
      public void packageDeleted(String arg0, int arg1) throws RemoteException {
      }
}, 0);
deletePackage


Android 应用卸载

通过 Intent 机制,调出系统卸载应用。
Uri packageURI = Uri.parse("package: your.app.id ");
Intent intent = new Intent(Intent. ACTION_DELETE );
startActivity(intent);
ACTION_DELETE

 


3.3 安装应用返回值

 //应用安装错误代码
/**
 * 文件解压失败
 */
public final static int ERROR_INSTALL_UNZIP_FAIL=13;

/**
 * 文件解密失败
 */
public final static int ERROR_INSTALL_DECODE_FAIL=14;

/**
 * 安装时没有足够空间
 */
public final static int ERROR_INSTALL_OUT_0F_SPACE=15;


/**
 * 该应用已经存在
 */
public final static int ERROR_ALREADY_EXISTS=-1;

/**
 * 无效的apk文件
 */
public final static int ERROR_INVALID_APK=-2;
/**
 * if the URI passed in is invalid.
 * 无效的链接
 */
public static final int ERROR_INSTALL_FAILED_INVALID_URI = -3;


/**
 * if the package manager service found that the device
 *   didn't have enough storage space to install the app.
 * 没有足够的存储空间
 */
public static final int ERROR_INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;


/**
 * if a package is already installed with the same name.
 * 已存在同名程序
 */
public static final int ERROR_INSTALL_FAILED_DUPLICATE_PACKAGE = -5;


/**
 * if the requested shared user does not exist.
 * 共享用户不存在
 */
public static final int ERROR_INSTALL_FAILED_NO_SHARED_USER = -6;


/**
 * if a previously installed package of the same name has a different signature
 *   than the new package (and the old package's data was not removed).
 * 更新不兼容
 */
public static final int ERROR_INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;


/**
 * if the new package is requested a shared user which is already installed
 *   on the device and does not have matching signature.
 * 共享用户不兼容
 */
public static final int ERROR_INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;


/**
 * if the new package uses a shared library that is not available.
 * 共享库已丢失
 */
public static final int ERROR_INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;


/**
 * if the new package uses a shared library that is not available.
 * 替换时无法删除
 */
public static final int ERROR_INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;


/**
 * if the new package failed while optimizing and validating its dex files,
 *   either because there was not enough storage or the validation failed.
 * 空间不足或验证失败
 */
public static final int ERROR_INSTALL_FAILED_DEXOPT = -11;


/**
 * if the new package failed because the current SDK version is older than
 * that required by the package.
 * 系统版本过旧
 */
public static final int ERROR_INSTALL_FAILED_OLDER_SDK = -12;


/**
 * if the new package failed because it contains a content provider with the
 *   same authority as a provider already installed in the system.
 * 存在同名的内容提供者
 */
public static final int ERROR_INSTALL_FAILED_CONFLICTING_PROVIDER = -13;


/**
 * if the new package failed because the current SDK version is newer than
 *   that required by the package.
 * 系统版本过新
 */
public static final int ERROR_INSTALL_FAILED_NEWER_SDK = -14;


/**
 * if the new package failed because it has specified that it is a test-only
 *   package and the caller has not supplied the {
 *   flag.
 * 调用者不被允许测试的测试程序
 */
public static final int ERROR_INSTALL_FAILED_TEST_ONLY = -15;


/**
 * if the package being installed contains native code, but none that is
 *   compatible with the the device's CPU_ABI.
 * 包含的本机代码不兼容CPU_ABI
 */
public static final int ERROR_INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;


/**
 * if the new package uses a feature that is not available.
 * 使用了一个无效的特性
 */
public static final int ERROR_INSTALL_FAILED_MISSING_FEATURE = -17;


// ------ Errors related to sdcard
/**
 * if a secure container mount point couldn't be accessed on external media.
 * SD卡访问失败
 */
public static final int ERROR_INSTALL_FAILED_CONTAINER_ERROR = -18;


/**
 * if the new package couldn't be installed in the specified install location.
 * 无效的安装路径
 */
public static final int ERROR_INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;


/**
 * if the new package couldn't be installed in the specified install
 *   location because the media is not available.
 * SD卡不可用
 */
public static final int ERROR_INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;


/**
 * if the new package couldn't be installed because the verification timed out.
 * 验证超时
 */
public static final int ERROR_INSTALL_FAILED_VERIFICATION_TIMEOUT = -21;


/**
 * if the new package couldn't be installed because the verification did not succeed.
 * 验证失败
 */
public static final int ERROR_INSTALL_FAILED_VERIFICATION_FAILURE = -22;


/**
 * if the package changed from what the calling program expected.
 * 预期的应用被改变
 */
public static final int ERROR_INSTALL_FAILED_PACKAGE_CHANGED = -23;


/**
 * if the parser was given a path that is not a file, or does not end
 *   with the expected '.apk' extension.
 * 解析失败,不是APK
 */
public static final int ERROR_INSTALL_PARSE_FAILED_NOT_APK = -100;


/**
 * if the parser was unable to retrieve the AndroidManifest.xml file.
 * 解析失败,无法提取Manifest
 */
public static final int ERROR_INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;


/**
 * if the parser encountered an unexpected exception.
 * 解析失败,无法预期的异常
 */
public static final int ERROR_INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;


/**
 * if the parser did not find any certificates in the .apk.
 * 解析失败,找不到证书
 */
public static final int ERROR_INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;


/**
 * if the parser found inconsistent certificates on the files in the .apk.
 * 解析失败,证书不一致
 */
public static final int ERROR_INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;


/**
 * if the parser encountered a CertificateEncodingException in one of the
 *   files in the .apk.
 * 解析失败,证书编码异常
 */
public static final int ERROR_INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;


/**
 * if the parser encountered a bad or missing package name in the manifest.
 * 解析失败,manifest中的包名错误或丢失
 */
public static final int ERROR_INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;


/**
 * if the parser encountered a bad shared user id name in the manifest.
 * 解析失败,manifest中的共享用户错误
 */
public static final int ERROR_INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;


/**
 * if the parser encountered some structural problem in the manifest.
 * 解析失败,manifest中出现结构性错误
 */
public static final int ERROR_INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;


/**
 * if the parser did not find any actionable tags (instrumentation or application)
 *   in the manifest.
 * 解析失败,manifest中没有actionable tags
 */
public static final int ERROR_INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;


/**
 * if the system failed to install the package because of system issues.
 * 系统问题导致安装失败
 */
public static final int ERROR_INSTALL_FAILED_INTERNAL_ERROR = -110;

/**
 * 应用商店被配置了黑名单,禁止了安装
 */
public final static int ERROR_INSTALL_FAILED_BLACKAPP_LIST = -111;

/**
 * apk文件MD5校验失败
 */
public final static int ERROR_APK_MD5_DIFFERENT = -112;
应用安装失败的返回值


四、获取应用信息

 

4.1 获取PackageInfo 
通过apk路径获取PackageInfo 
PackageInfo pkgInfo = mPackageManager.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);

通过应用包名获取PackageInfo 
getPackageManager().getPackageInfo(packageName, 0)

通过权限组来获取PackageInfo
List<PackageInfo> pkgInfos = mPackageManager.getPackagesHoldingPermissions(permsArray, 0);

通过获取所有已安装应用列表
List<PackageInfo> installedList = context.getPackageManager().getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);

4.2 获取ApplicationInfo 
Context 直接获取ApplicationInfo 
context.getApplicationInfo()

通过PackageInfo 获取ApplicationInfo 
packageInfo.applicationInfo

获取所有安装应用的ApplicationInfo
List<ApplicationInfo> appList = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);

通过包名获取ApplicationInfo
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
ApplicationInfo ai = pm.getApplicationInfo(pakName, PackageManager.GET_META_DATA);

通过ComponentInfo 获取 ApplicationInfo 
componentInfo.applicationInfo

android.content.pm.ResolveInfo  里面持有所有组件的实例

组件的继承关系:
java.lang.Object
  android.content.pm.PackageItemInfo
    android.content.pm.ComponentInfo
      android.content.pm.ActivityInfo
      android.content.pm.ProviderInfo
      android.content.pm.ServiceInfo


4.3 获取ActivityInfo
通过PackageManager 获取ActivityInfo 
mPkgmanager.getActivityInfo(new ComponentName(pkgName, className), 0);

通过 ResolveInfo  获取ActivityInfo
resolveInfo.ActivityInfo

五、查询、增加或者删除应用的权限 permission
List<PackageInfo> pkgInfos = mPackageManager.getPackagesHoldingPermissions(permsArray, 0);

public List<PackageInfo> getPackageInfoByOps(int [] ops){
        
        ArrayList <String> perms = new ArrayList<String>();
        List<PackageInfo> pkgInfos = new ArrayList<PackageInfo>();
        
        for(int i=0; i<ops.length; i++){
            
            String perm = AppOpsManager.opToPermission(ops[i]);
            if (!perms.contains(perm)){
                perms.add(perm);
            }
        }
        
        Log.d(TAG, "get perms.size: "+ perms.size());
        String[] permsArray = new String[perms.size()];
        perms.toArray(permsArray);
        
        pkgInfos = mPackageManager.getPackagesHoldingPermissions(permsArray, 0);
        Log.d(TAG, "get pkgInfos.size: "+ pkgInfos.size());
        
        return pkgInfos;
        
    }
getPackageInfoByOps


通过包名查询应用申请的所有权限

PackageManager mPm = mContext.getPackageManager();
 
private List<PermissionInfo>  getPermissions(Context context, String packageName) {
    mContext = context;
    mPm = mContext.getPackageManager();
    List<PermissionInfo> mPermsList = new ArrayList<PermissionInfo>();
    
    Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
    PackageInfo pkgInfo;
    try {
        pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
    } catch (NameNotFoundException e) {
        Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
        return;
    }
    // Extract all user permissions
    if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
        getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
    }
    Log.d(TAG, "getPermissions permSet size "+permSet.size());
    for(PermissionInfo tmpInfo : permSet) {
        mPermsList.add(tmpInfo);
    }
    return mPermsList
}

private void getAllUsedPermissions(int sharedUid, Set<PermissionInfo> permSet) {
    String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
    if(sharedPkgList == null || (sharedPkgList.length == 0)) {
        return;
    }
    for(String sharedPkg : sharedPkgList) {
        getPermissionsForPackage(sharedPkg, permSet);
    }
}

private void getPermissionsForPackage(String packageName, 
        Set<PermissionInfo> permSet) {
    PackageInfo pkgInfo;
    try {
        pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
    } catch (NameNotFoundException e) {
        Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
        return;
    }
    if ((pkgInfo != null) && (pkgInfo.requestedPermissions != null)) {
        extractPerms(pkgInfo.requestedPermissions, permSet);
    }
}

private void extractPerms(String strList[], Set<PermissionInfo> permSet) {
    if((strList == null) || (strList.length == 0)) {
        return;
    }
    for(String permName:strList) {
        try {
            PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
            if(tmpPermInfo != null) {
                permSet.add(tmpPermInfo);
            }
        } catch (NameNotFoundException e) {
            Log.i(TAG, "Ignoring unknown permission:"+permName);
        }
    }
}
获取应用的PermissionInfo

 


查询监听了开机广播的组件但是被禁止的ResolveInfo

Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
List<ResolveInfo> resolveInfoList = pm.queryBroadcastReceivers(intent, PackageManager.GET_DISABLED_COMPONENTS);

获取应用的签名信息

String pkgMd5 = getSignInfo(context, packageName);

/**
 * 获取对应包名的md5信息,不带冒号
 *
 * @param context
 * @param packageName
 * @return
 */
public static final String getSignInfo(Context context, String packageName) {
    PackageManager localPackageManager = context.getPackageManager();
    PackageInfo localPackageInfo;
    try {
        localPackageInfo = localPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        if (localPackageInfo == null) {
            return "";
        }
    } catch (PackageManager.NameNotFoundException localNameNotFoundException) {
        return "";
    }
    Signature[] arrayOfSignature = localPackageInfo.signatures;
    if (arrayOfSignature == null || arrayOfSignature.length == 0) {
        return "";
    }
    return getMessageDigest(arrayOfSignature[0].toByteArray(), packageName);
}

 /**
 * 获取apk签名信息里的MD5算法
 *
 * @param paramArrayOfByte
 * @return
 */
public static final String getMessageDigest(byte[] paramArrayOfByte, String packageName) {
    char[] arrayOfChar1 = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98,
            99, 100, 101, 102};
    try {
        MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
        localMessageDigest.update(paramArrayOfByte);
        byte[] arrayOfByte = localMessageDigest.digest();
        int i = arrayOfByte.length;
        char[] arrayOfChar2 = new char[i * 2];
        int j = 0;
        int k = 0;
        while (true) {
            if (j >= i){
                return new String(arrayOfChar2);
            }
            int m = arrayOfByte[j];
            int n = k + 1;
            arrayOfChar2[k] = arrayOfChar1[(0xF & m >>> 4)];
            k = n + 1;
            arrayOfChar2[n] = arrayOfChar1[(m & 0xF)];
            j++;
        }
    } catch (Exception localException) {
        LLogUtils.i("通过包名" + packageName + "获取签名md5失败");
    }
    return null;
}
获取应用签名的md5

 


判断Intent 跳转的组件是否存在

 public static boolean isActionExisted(Context context, Intent intent) {
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> resolveInfo =
                packageManager.queryIntentActivities(intent,
                        PackageManager.MATCH_DEFAULT_ONLY);
        return resolveInfo.size() > 0;
    }
isActionExisted

Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setPackage(installerPackageName);
List<ResolveInfo> resolveInfos = mPm.queryIntentActivities(intent, PackageManager.GET_INTENT_FILTERS);


六、清除应用数据
6.1 获取应用的数据大小

调用 :long[] appSize = getApplicationSize(appInfo.packageName);

private class SizeObserver extends IPackageStatsObserver.Stub {
    private CountDownLatch mCount;
    PackageStats stats;
    boolean succeeded;

    public void invokeGetSize(String packageName, CountDownLatch count) {
        mCount = count;
        mPkgmanager.getPackageSizeInfo(packageName, this);
    }

    public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
        succeeded = pSucceeded;
        stats = pStats;
        mCount.countDown();
    }
}


private long[] getApplicationSize(String packageName){
    long appSize[] = new long[2];
    if(android.os.Build.VERSION.SDK_INT >= 26){
        appSize = getCacheSizeForAndroidO( MyApplication.getContextObject(), packageName);
    }else {
        CountDownLatch count = new CountDownLatch(1);
        mSizeObserver.invokeGetSize(packageName, count);
        try {
            count.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        PackageStats pStats = mSizeObserver.stats;
        boolean succeeded = mSizeObserver.succeeded;
        if (succeeded && pStats != null) {
            Log.d(TAG, "getCacheSize cacheSize = " + pStats.cacheSize + ", externalCacheSize = " + pStats.externalCacheSize);
            appSize[0] = pStats.codeSize;
            appSize[1] = pStats.cacheSize + pStats.dataSize;
        }
    }
    return appSize;
}

public long[]  getCacheSizeForAndroidO(Context context, String packageName){
    long appSize[] = new long[2];
    try {
        StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService("storagestats");//Context.STORAGE_STATS_SERVICE
        //StorageManager storageManager= (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
        UUID uuid = UUID
                .fromString("41217664-9172-527a-b3d5-edabb50a7d69");//StorageManager.UUID_DEFAULT

        UserManager mUserManager=(UserManager) context.getSystemService(Context.USER_SERVICE);;
        List<UserInfo> allUsers = mUserManager.getUsers();
        Log.d("rubbish", "allUsers:" + allUsers.size());
        if(allUsers.size()<1){
            return appSize;
        }
//            int uid = getUid(context, packageName);
//            StorageStats storageStats = storageStatsManager.queryStatsForUid(uuid, uid);
        StorageStats storageStats = null;
        try {
            storageStats = storageStatsManager.queryStatsForPackage(uuid, packageName, allUsers.get(0).getUserHandle());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(storageStats==null){
            return appSize ;
        }
        Log.d("dony", "getCacheBytes :" + storageStats.getAppBytes());

        appSize[0] = storageStats.getAppBytes();
        appSize[1] = storageStats.getDataBytes() + storageStats.getAppBytes();
        return appSize ;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return appSize;
}

public int getUid(Context context, String pakName) {
    PackageManager pm = context.getPackageManager();
    try {
        ApplicationInfo ai = pm.getApplicationInfo(pakName, PackageManager.GET_META_DATA);
        return ai.uid;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return -1;
}
获取应用大小兼容8.0


和上面代码一样 (获取cache、data、app)

AppSize appsize = null;
if(android.os.Build.VERSION.SDK_INT >= 26){
    appsize = getAppSizeForAndroidO(mContext, packageName);
}else {
    appsize = getAppSize(packageName, sizeObserver) ;
}

private class AppSize{
    public long cacheSize = 0;
    public long dataSize = 0;
    public long appSize = 0;
}

private AppSize getAppSizeForAndroidO(Context context, String packageName){
    try {
        UUID uuid = UUID
                .fromString("41217664-9172-527a-b3d5-edabb50a7d69");//StorageManager.UUID_DEFAULT
        //通过包名获取uid
        UserManager mUserManager=(UserManager) context.getSystemService(Context.USER_SERVICE);;
        List<UserInfo> allUsers = mUserManager.getUsers();
        Log.d("rubbish", "allUsers:" + allUsers.size());
        if(allUsers.size()<1){
            return new AppSize();
        }

        StorageStats storageStats=storageStatsManager.queryStatsForPackage(uuid, packageName, allUsers.get(0).getUserHandle());
        AppSize appSize = new AppSize();
        appSize.cacheSize = storageStats.getCacheBytes();
        appSize.dataSize = storageStats.getDataBytes();
        appSize.appSize = storageStats.getAppBytes() ;
        Log.d("rubbish","getCacheSize packageName:" +packageName
                +",cachesize:"+storageStats.getCacheBytes()
                +",datasize:"+ storageStats.getDataBytes()
                +",appSize:" + storageStats.getAppBytes());
        return appSize;
        //获取到App的总大小
        //appSizeL = storageStats.appBytes + storageStats.cacheBytes + storageStats.dataBytes
    } catch (Exception e) {
        e.printStackTrace();
        Log.d("rubbish", "getAppSizeForAndroidO: " + e.toString());
    }
    return null;
}

private AppSize getAppSize(String packageName,SizeObserver sizeObserver){
    CountDownLatch count = new CountDownLatch(1);
    if(sizeObserver == null) {
        return null;
    }
    sizeObserver.invokeGetSize(packageName, count);

    try {
        count.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    PackageStats pStats = sizeObserver.stats;
    boolean succeeded = sizeObserver.succeeded;

    AppSize appSize = new AppSize();

    if (succeeded && pStats != null) {
        appSize.cacheSize = pStats.cacheSize;
        appSize.dataSize = pStats.dataSize ;
        appSize.appSize = pStats.codeSize;
    } else {
        appSize.cacheSize = 0;
        appSize.dataSize = 0 ;
        appSize.appSize = 0;
    }

    return appSize ;
}
获取应用大小cache、data、app

 

清除应用缓存大小

public void clearCacheData(String packageName) {
    if (TextUtils.isEmpty(packageName)) {
        return;
    }
    Log.d(TAG, "StartDelete ClearCacheData packageName = " + packageName);
    try{
        pm.deleteApplicationCacheFiles(packageName,
                new IPackageDataObserver.Stub() {                    
                    @Override
                    public void onRemoveCompleted(String packageName, boolean succeeded)
                            throws RemoteException {
                    }
            });
    }catch(Exception e){
        e.printStackTrace();
        Log.d(TAG, "StartDelete ClearCacheData Exception");
    }
}
clearCacheData


清除应用data数据 (/data/data/包名/)

/**
 * clean data
 * @param packageName
 */
private void clearUserData(String packageName) {
    

    if (mClearDataObserver == null) {
        mClearDataObserver = new ClearUserDataObserver();
    }
    ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
    Log.i(TAG, "initiateClearUserData ,packageName=" + packageName);
}

class ClearUserDataObserver extends IPackageDataObserver.Stub {
    public void onRemoveCompleted(final String packageName,
            final boolean succeeded) {
        Message msg = new Message();
        msg.what = MessageType.MSG_RUBBSIH_DELETE_COMPLETE;
        mHandler.sendMessage(msg);
    }
}
清除应用所有data数据

 

七、应用可设置的状态
7.1 stop和default 状态
把应用设置为stop 状态

    /**
     * 把应用stop 掉
     * @param context context
     * @param pkgName 包名
     */
    private static void stopPackage(Context context,String pkgName) {
        if (mActivityManager == null) {
            mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            if (mActivityManager ==null){
                return;
            }
        }
        try {
            ActivityManagerNative.getDefault().forceStopPackage(pkgName, UserHandle.myUserId());
        }catch (Exception e){
            LLogUtils.d("exception:" + e.toString());
        }
    }
把应用设置为stop状态


把应用设置为default状态 

/**
* 设置应用的状态为default ,即恢复被stop的应用的状态
* packageName 包名
*/
private static void setPackageDefaultState(String packageName){
    if (!TextUtils.isEmpty(packageName)) {
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(packageName, false, UserHandle.myUserId());
        }catch (Exception e){
            LLogUtils.d(TAG,"exception :" + e.toString());
        }
    }
}
把应用设置为default状态

 

7.2 hide和unhide 状态 同一个接口
IPackageManager mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));

获取应用的状态,返回 true 表示应用被隐藏, 返回false 表示应用被设置为unhide 一般安装后的应用都属于这个状态
mPm.getApplicationHiddenSettingAsUser(pkgName, UserHandle.myUserId());    

设置应用的hide 状态,第二个参数 true 表示把应用设置为hide,false 表示设置为unhide状态
mPm.setApplicationHiddenSettingAsUser(pkgName, true, UserHandle.myUserId());

7.3 把应用设置为 enable 和 disable状态

下面代码是通过应用包名先获取应用的状态,如果没有被disable ,则会把应用状态给disable 掉
if (mPm.getApplicationEnabledSetting(packageName) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
  mPm.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
}







posted @ 2018-08-14 21:45  dony_c  阅读(1927)  评论(0)    收藏  举报