包管理之隐藏apk

原创 2013年12月05日 22:29:16

在\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");
    }





版权声明:本文为博主原创文章,未经博主允许不得转载。

android包管理器以及apk文件安装流程

PackageInstaller 原理简述   应用安装是智能机的主要特点,即用户可以把各种应用(如游戏等)安装到手机上,并可以对其进行卸载等管理操作。APK是Android Packag...
  • andy205214
  • andy205214
  • 2013年04月08日 22:03
  • 3063

apk增量更新的初步实现

在市场下我们经常见到省流量更新,特别是游戏类的apk,假如一个游戏apk有100M,那我下次版本有110M,我是不是要下载这110M的apk呢?这显然在用户的角度是不合理的,增量更新就是只要用户下载这...
  • qq_17387361
  • qq_17387361
  • 2016年10月25日 17:12
  • 641

提取应用的签名和包名

欢迎Follow我的GitHub, 关注我的CSDN, 未经授权, 禁止转载. Android应用在使用第三方的库时, 可能需要申请密钥, 表明应用身份, 如高德定位SDK等. 应用签名(printc...
  • u012515223
  • u012515223
  • 2016年04月28日 16:25
  • 5754

Android APK文件拆解方法

以下操作皆在Win环境下完成,默认已经安装了Android开发的需要各种杂七杂八的东西(其实这里需要只是JRE而已……)。 1 解压apk文件。   apk文件实质上只是一个压缩包,所以随便用点win...
  • hnulwt
  • hnulwt
  • 2014年09月24日 17:27
  • 3627

获取APK包名的几种方法

http://www.cnblogs.com/dzblog/p/4062288.html Android自动化学习笔记:获取APK包名的几种方法 -------...
  • muyimo
  • muyimo
  • 2015年08月27日 18:00
  • 8421

减小Apk包大小的常用方法

我们之所以要减小apk的大小,一方面是为了节省用户手机的内存;另一方面是为了节省用户在App安装和版本升级时的流量; 直接减小apk文件大小的方法: 1.使用图片压缩工具; 目前常用的工具是:Ima...
  • chwnpp2
  • chwnpp2
  • 2016年06月23日 20:26
  • 1280

BAT - 通过脚本直接从apk文件获取包名等信息

BAT - 通过脚本直接从apk文件获取包名等信息 有时,我需要从android应用包里直接获取到应用程序的包名,别的不需要,此时想方便快捷的拿到想到的信息,只需要打开命令行窗口,然后输入命令 a...
  • lys211
  • lys211
  • 2015年05月13日 21:13
  • 1119

APK反编译修改包名及相应的基础文件信息

仅供技术交流学习       apk反编译已经得到广泛的应用,大部分反编译的目的则是查看相应apk的代码编写及学习,(不包括发现软件的漏洞),此文带来的只是修改包名重新打包,目的只有满足在同个手机安...
  • w305172521
  • w305172521
  • 2016年09月05日 10:48
  • 3435

查看Android应用包名、Activity的几个方法

查看Android应用包名、Activity的几个方法
  • jlminghui
  • jlminghui
  • 2014年10月30日 16:25
  • 91949

PHP读取APK的包信息,包括包名,应用名,权限,LOGO等

/** * 获取 APK 包信息和应用图标(需要exec支持) */ public function apkParseInfo($apk) { $aapt...
  • Nil88
  • Nil88
  • 2017年05月27日 15:28
  • 668
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:包管理之隐藏apk
举报原因:
原因补充:

(最多只允许输入30个字)