怎么在APK安装之前获取签名或包名,对不符合条件的APK阻止安装。程序是在电视盒子上运行。
1条回答 默认 最新
- Hunter-Lei 2017-05-09 07:00关注
byte[] signature = getSign(context);
String installPublickey = getPublicKey(signature);//已安装的应用APK签名信息获取
//apkFile :下载的未安装APK的安装包路径,如:
String apkFile = Environment.getExternalStorageDirectory() + "/download/xxxx.apk";
byte[] unstallSignature = getPackageArchiveInfo(apkFile, PackageManager.GET_ACTIVITIES | PackageManager.GET_SIGNATURES);
String unInstallPublickey = getPublicKey(unstallSignature );//未安装的APK包的签名信息获取
//下面是方法private static byte[] getSign(Context context) {
PackageManager pm = context.getPackageManager();
List apps = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
Iterator iter = apps.iterator();
while (iter.hasNext()) {
PackageInfo info = iter.next();
String packageName = info.packageName;
//按包名读取签名
if (packageName.equals("com.XXX.XXX")) { //根据你自己的包名替换
return info.signatures[0].toByteArray();
}
}
return null;
}@SuppressWarnings({ "unchecked", "rawtypes" })
public static byte[] getPackageArchiveInfo(String apkFile, int flags){//这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况 DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); Object pkgParserPkg = null; Class[] typeArgs = null; Object[] valueArgs = null; try { Class<?> packageParserClass = Class.forName("android.content.pm.PackageParser"); Constructor<?> packageParserConstructor = null; Object packageParser = null; //由于SDK版本问题,这里需做适配,来生成不同的构造函数 if (Build.VERSION.SDK_INT > 20) { //无参数 constructor packageParserConstructor = packageParserClass.getDeclaredConstructor(); packageParser = packageParserConstructor.newInstance(); packageParserConstructor.setAccessible(true);//允许访问 typeArgs = new Class[2]; typeArgs[0] = File.class; typeArgs[1] = int.class; Method pkgParser_parsePackageMtd = packageParserClass.getDeclaredMethod("parsePackage", typeArgs); pkgParser_parsePackageMtd.setAccessible(true); valueArgs = new Object[2]; valueArgs[0] = new File(apkFile); valueArgs[1] = PackageManager.GET_SIGNATURES; pkgParserPkg = pkgParser_parsePackageMtd.invoke(packageParser, valueArgs); } else { //低版本有参数 constructor packageParserConstructor = packageParserClass.getDeclaredConstructor(String.class); Object[] fileArgs = { apkFile }; packageParser = packageParserConstructor.newInstance(fileArgs); packageParserConstructor.setAccessible(true);//允许访问 typeArgs = new Class[4]; typeArgs[0] = File.class; typeArgs[1] = String.class; typeArgs[2] = DisplayMetrics.class; typeArgs[3] = int.class; Method pkgParser_parsePackageMtd = packageParserClass.getDeclaredMethod("parsePackage", typeArgs); pkgParser_parsePackageMtd.setAccessible(true); valueArgs = new Object[4]; valueArgs[0] = new File(apkFile); valueArgs[1] = apkFile; valueArgs[2] = metrics; valueArgs[3] = PackageManager.GET_SIGNATURES; pkgParserPkg = pkgParser_parsePackageMtd.invoke(packageParser, valueArgs); } typeArgs = new Class[2]; typeArgs[0] = pkgParserPkg.getClass(); typeArgs[1] = int.class; Method pkgParser_collectCertificatesMtd = packageParserClass.getDeclaredMethod("collectCertificates", typeArgs); valueArgs = new Object[2]; valueArgs[0] = pkgParserPkg; valueArgs[1] = PackageManager.GET_SIGNATURES; pkgParser_collectCertificatesMtd.invoke(packageParser, valueArgs); // 应用程序信息包, 这个公开的, 不过有些函数变量没公开 Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures"); Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg); return info[0].toByteArray(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null;
}
public static String getPublicKey(byte[] signature) {
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
return cert.getPublicKey().toString();
} catch (CertificateException e) {
e.printStackTrace();
}
return null;
}解决 无用评论 打赏 举报
悬赏问题
- ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
- ¥20 yolov5自定义Prune报错,如何解决?
- ¥15 电磁场的matlab仿真
- ¥15 mars2d在vue3中的引入问题
- ¥50 h5唤醒支付宝并跳转至向小荷包转账界面
- ¥15 算法题:数的划分,用记忆化DFS做WA求调
- ¥15 chatglm-6b应用到django项目中,模型加载失败
- ¥15 CreateBitmapFromWicBitmap内存释放问题。
- ¥30 win c++ socket
- ¥15 C# datagridview 栏位进度