包管理之隐藏apk

本文介绍了Android系统中如何通过PackageManagerService的Settings.java文件实现APK的隐藏与显示功能。通过disableSystemPackageLPw方法将指定包名的应用加入到mDisabledSysPackages列表中实现隐藏,并可通过enableSystemPackageLPw方法恢复显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在\frameworks\base\services\java\com\android\server\pm目录下的Settings.java中,提供了隐藏apk的方法。

被隐藏的apk存储在mDisabledSysPackages中:

    // List of replaced system applications
    private final HashMap<String, PackageSetting> mDisabledSysPackages =
        new HashMap<String, PackageSetting>();

disableSystemPackageLPw方法可以隐藏apk,它会根据packagename去隐藏对应的apk:
    boolean disableSystemPackageLPw(String name) {
		//一定能在mPackages中找到需要隐藏的apk对应的PackageSetting
        final PackageSetting p = mPackages.get(name);
        if(p == null) {
            Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
            return false;
        }
		//在mDisabledSysPackages中不能找到这个apk的信息
        final PackageSetting dp = mDisabledSysPackages.get(name);
        // always make sure the system package code and resource paths dont change
        if (dp == null) {
            //设置标志位FLAG_UPDATED_SYSTEM_APP
            if((p.pkg != null) && (p.pkg.applicationInfo != null) &&
                    ((p.pkgFlags & ApplicationInfo.FLAG_UNINSTALL_APP) != 0)) {
                p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
            }
			//添加到mDisabledSysPackages中
            mDisabledSysPackages.put(name, p);

            // a little trick...  when we install the new package, we don't
            // want to modify the existing PackageSetting for the built-in
            // version.  so at this point we need a new PackageSetting that
            // is okay to muck with.
            PackageSetting newp = new PackageSetting(p);
            replacePackageLPw(name, newp);
            return true;
        }
        return false;
    }

    PackageSetting enableSystemPackageLPw(String name) {
		//在mDisabledSysPackages中查找,必须能查找到
        PackageSetting p = mDisabledSysPackages.get(name);
        if(p == null) {
            Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
            return null;
        }
        // 清除标志位FLAG_UPDATED_SYSTEM_APP
        if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
            p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
        }
		//add package
        PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
                p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
		//从mDisabledSysPackages中删除改apk
        mDisabledSysPackages.remove(name);
        return ret;
    }

    boolean isDisabledSystemPackageLPr(String name) {
        return mDisabledSysPackages.containsKey(name);
    }

    void removeDisabledSystemPackageLPw(String name) {
        mDisabledSysPackages.remove(name);
    }


writeDisabledSysPackageLPr方法会把mDisabledSysPackages写入到packages.xml文件中,以updated-package开始和结束,标记这是被隐藏的apk。
for (final PackageSetting pkg : mDisabledSysPackages.values()) {
     writeDisabledSysPackageLPr(serializer, pkg);
}

    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
            throws java.io.IOException {
        serializer.startTag(null, "updated-package");
        serializer.attribute(null, ATTR_NAME, pkg.name);
        if (pkg.realName != null) {
            serializer.attribute(null, "realName", pkg.realName);
        }
        serializer.attribute(null, "codePath", pkg.codePathString);
        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
        /// M: [Vendor] Add package flags recording in disabled pacakge element
        serializer.attribute(null, "flags", String.valueOf(pkg.pkgFlags));
        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
        }
        if (pkg.nativeLibraryPathString != null) {
            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
        }
        if (pkg.sharedUser == null) {
            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
        } else {
            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
        }
        serializer.startTag(null, "perms");
        if (pkg.sharedUser == null) {
            // If this is a shared user, the permissions will
            // be written there. We still need to write an
            // empty permissions list so permissionsFixed will
            // be set.
            for (final String name : pkg.grantedPermissions) {
                BasePermission bp = mPermissions.get(name);
                if (bp != null) {
                    // We only need to write signature or system permissions but
                    // this wont
                    // match the semantics of grantedPermissions. So write all
                    // permissions.
                    serializer.startTag(null, TAG_ITEM);
                    serializer.attribute(null, ATTR_NAME, name);
                    serializer.endTag(null, TAG_ITEM);
                }
            }
        }
        serializer.endTag(null, "perms");
        serializer.endTag(null, "updated-package");
    }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值