反射获取包名的方法:
/**
* <br>功能简述:采用反射获取包名
* <br>功能详细描述:
* <br>注意:
* @param ctx
* @param apkPath
* @return
*/
private static HashMap<String, String> sApkPathMap;
public static String getApkFileInfoFromReflect(Context ctx, String apkPath) {
File apkFile = new File(apkPath);
if (!apkFile.exists() || !apkPath.toLowerCase().endsWith(".apk")) {
return null;
}
if (sApkPathMap != null) {
synchronized (sApkPathMap) {
Iterator iter = sApkPathMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
if (val != null && ((String) val).equals(apkPath)) {
return (String) key;
}
}
}
}
String PATH_PackageParser = "android.content.pm.PackageParser";
String PATH_AssetManager = "android.content.res.AssetManager";
try {
// 反射得到pkgParserCls对象并实例化,有参数
// apk包的文件路径
// 这是一个Package 申明器, 是隐蔽的
// 构造函数的参数只有一个, apk文件的路径
Class<?> pkgParserCls = Class.forName(PATH_PackageParser);
Class<?>[] typeArgs = { String.class };
Constructor<?> pkgParserCt = pkgParserCls.getConstructor(typeArgs);
Object[] valueArgs = { apkPath };
Object pkgParser = pkgParserCt.newInstance(valueArgs);
// 从pkgParserCls类得到parsePackage方法
// 这个是与显示有关的, 里面涉及到一些像素显示等等
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults(); // 这个是与显示有关的, 这边使用默认
typeArgs = new Class<?>[] { File.class, String.class, DisplayMetrics.class, int.class };
Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs);
valueArgs = new Object[] { new File(apkPath), apkPath, metrics, 0 };
// 执行pkgParser_parsePackageMtd方法并返回
Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);
// 从返回的对象得到名为"applicationInfo"的字段对象
if (pkgParserPkg == null) {
return null;
}
Field appInfoFld = pkgParserPkg.getClass().getDeclaredField("applicationInfo");
// 从对象"pkgParserPkg"得到字段"appInfoFld"的值
if (appInfoFld.get(pkgParserPkg) == null) {
return null;
}
ApplicationInfo info = (ApplicationInfo) appInfoFld.get(pkgParserPkg);
Log.d("ANDROID_LAB", "pkg:" + info.packageName + " uid=" + info.uid);
if (sApkPathMap == null) {
sApkPathMap = new HashMap<String, String>();
}
if (info.packageName != null) {
sApkPathMap.put(info.packageName, apkPath);
}
return info.packageName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
其他地方调用此方法获取包名:
String packageName = getApkFileInfoFromReflect(Const.ZIP_PATH + fileName);