Android L反射扫描不到包名原因

来源:互联网 发布:淘宝手机详情空间不够 编辑:程序博客网 时间:2024/06/06 00:27

由于我们是调用了隐藏的API 。这部分通过反射方法拿到。。在android L之后版本,这一隐藏API接口的构造方式有所改变,从而导致了该实现方式无法构造Constructor类成功,需要针对版本进行区分调用构造该对象。

 

Android L版本前的构造方法

Class pkgParserCls = Class.forName(path_packageparser);

Object[] valueArgs = new Object[1];

Constructor pkgParserCt =pkgParserCls.getConstructor(typeArgs);

valueArgs[0] = apkPath;

Object pkgParser = pkgParserCt.newInstance(valueArgs);

 

Android L版本开始后的构造方法

 ClasspkgParserCls = Class.forName(path_packageparser);

 ConstructorpkgParserCt =null;

pkgParserCt = pkgParserCls.getConstructor(null);

Object pkgParser = pkgParserCt.newInstance(null);

 

有源码的同学可以对比两个版本去参看一下,它构造方式的改变


 ZipResources类内

修改后的方法

public static StringgetThemePkgFromReflect(String apkPath) {

if (null == apkPath || apkPath.length() < 0) {

return LauncherEnv.Package.PACKAGE_NAME;

}

if (sThemePathMap !=null) {

Iterator iter =sThemePathMap.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";

try {

// apk包的文件路径

// 这是一个Package 申明器, 是隐蔽的

// 构造函数的参数只有一个, apk文件的路径

Class pkgParserCls = Class.forName(path_packageparser);

Constructor pkgParserCt =null;

Object pkgParserPkg =null;

if (Build.VERSION.SDK_INT < 21) {

Class[] typeArgs =new Class[1];

typeArgs[0] = String.class;

pkgParserCt = pkgParserCls.getConstructor(typeArgs);

Object[] valueArgs =new Object[1];

valueArgs[0] = apkPath;

Object pkgParser = pkgParserCt.newInstance(valueArgs);

// 这个是与显示有关的, 里面涉及到一些像素显示等等

DisplayMetrics metrics = newDisplayMetrics();

metrics.setToDefaults();

 

typeArgs = new Class[4];

typeArgs[0] = File.class;

typeArgs[1] = String.class;

typeArgs[2] = DisplayMetrics.class;

typeArgs[3] = Integer.TYPE;

Method pkgParser_parsePackageMtd =pkgParserCls.getDeclaredMethod("parsePackage",

typeArgs);

valueArgs = new Object[4];

valueArgs[0] = newFile(apkPath);

valueArgs[1] = apkPath;

valueArgs[2] = metrics;

valueArgs[3] = 0;

pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);

} else {

pkgParserCt = pkgParserCls.getConstructor(null);

Object pkgParser = pkgParserCt.newInstance(null);

Class[] typeArgs =new Class[2];

typeArgs[0] = File.class;

typeArgs[1] = Integer.TYPE;

Method pkgParser_parsePackageMtd =pkgParserCls.getDeclaredMethod("parsePackage",

typeArgs);

Object[] valueArgs =new Object[2];

valueArgs[0] = newFile(apkPath);

valueArgs[1] = 0;

pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);

}

// 应用法度信息包, 这个公开的, 不过有些函数,变量没公开

Field appInfoFld = pkgParserPkg.getClass().getDeclaredField("applicationInfo");

ApplicationInfo info = (ApplicationInfo) appInfoFld.get(pkgParserPkg);

// uid 输出为"-1",原因是未安装,体系未分派其Uid

//Log.d("ANDROID_LAB", "pkg:" + info.packageName + "uid=" + info.uid);

if (sThemePathMap ==null) {

sThemePathMap = new HashMap<String, String>();

}

if (info.packageName !=null) {

sThemePathMap.put(info.packageName, apkPath);

}

return info.packageName;

} catch (Exceptione) {

e.printStackTrace();

}

return LauncherEnv.Package.PACKAGE_NAME;

 

}

 

修改前的方法

public static StringgetThemePkgFromReflect(String apkPath) {

if (null == apkPath || apkPath.length() < 0) {

return LauncherEnv.PACKAGE_NAME;

}

if (sThemePathMap !=null) {

Iterator iter =sThemePathMap.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";

try {

// apk包的文件路径

// 这是一个Package 申明器, 是隐蔽的

// 构造函数的参数只有一个, apk文件的路径

Class[] typeArgs =new Class[1];

typeArgs[0] = String.class;

Object[] valueArgs =new Object[1];

Class pkgParserCls = Class.forName(path_packageparser);

Constructor pkgParserCt =pkgParserCls.getConstructor(typeArgs);

valueArgs[0] = apkPath;

Object pkgParser = pkgParserCt.newInstance(valueArgs);

// 这个是与显示有关的, 里面涉及到一些像素显示等等

DisplayMetrics metrics =new DisplayMetrics();

metrics.setToDefaults();

 

typeArgs = new Class[4];

typeArgs[0] = File.class;

typeArgs[1] = String.class;

typeArgs[2] = DisplayMetrics.class;

typeArgs[3] = Integer.TYPE;

Method pkgParser_parsePackageMtd =pkgParserCls.getDeclaredMethod("parsePackage",

typeArgs);

valueArgs = new Object[4];

valueArgs[0] = new File(apkPath);

valueArgs[1] = apkPath;

valueArgs[2] = metrics;

valueArgs[3] = 0;

Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);

// 应用法度信息包, 这个公开的, 不过有些函数,变量没公开

Field appInfoFld = pkgParserPkg.getClass().getDeclaredField("applicationInfo");

ApplicationInfo info = (ApplicationInfo) appInfoFld.get(pkgParserPkg);

// uid 输出为"-1",原因是未安装,体系未分派其Uid

Log.d("ANDROID_LAB", "pkg:" + info.packageName + " uid=" + info.uid);

if (sThemePathMap ==null) {

sThemePathMap = new HashMap<String, String>();

}

if (info.packageName !=null) {

sThemePathMap.put(info.packageName, apkPath);

}

return info.packageName;

} catch (Exceptione) {

e.printStackTrace();

}

return LauncherEnv.PACKAGE_NAME;

}

0 0