不说废话,只上代码:
package com.example.getapksign;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends ActionBarActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void getAPKSign(View view) {
Signature[] signatures=showUninstallAPKSignatures("/mnt/sdcard/360.apk");
parseSignature(signatures[0].toByteArray());
getSingInfo("com.lbe.security.miui");
}
public Signature[] showUninstallAPKSignatures(String apkPath) {
String PATH_PackageParser = "android.content.pm.PackageParser";
try {
// apk包的文件路径
// 这是一个Package 解释器, 是隐藏的
// 构造函数的参数只有一个, apk文件的路径
// PackageParser packageParser = new PackageParser(apkPath);
Class pkgParserCls = Class.forName(PATH_PackageParser);
Class[] typeArgs = new Class[1];
typeArgs[0] = String.class;
Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);
Object[] valueArgs = new Object[1];
valueArgs[0] = apkPath;
Object pkgParser = pkgParserCt.newInstance(valueArgs);
Log.i(TAG, "pkgParser:" + pkgParser.toString());
// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
// PackageParser.Package mPkgInfo = packageParser.parsePackage(new
// File(apkPath), apkPath,
// metrics, 0);
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] = PackageManager.GET_SIGNATURES;
Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
valueArgs);
typeArgs = new Class[2];
typeArgs[0] = pkgParserPkg.getClass();
typeArgs[1] = Integer.TYPE;
Method pkgParser_collectCertificatesMtd = pkgParserCls
.getDeclaredMethod("collectCertificates", typeArgs);
valueArgs = new Object[2];
valueArgs[0] = pkgParserPkg;
valueArgs[1] = PackageManager.GET_SIGNATURES;
pkgParser_collectCertificatesMtd.invoke(pkgParser, valueArgs);
// 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField(
"mSignatures");
Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
Log.i(TAG, info[0].toCharsString());
return info;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getSign(Context context) {
PackageManager pm = context.getPackageManager();
List<PackageInfo> apps = pm
.getInstalledPackages(PackageManager.GET_SIGNATURES);
Iterator<PackageInfo> iter = apps.iterator();
while (iter.hasNext()) {
PackageInfo packageinfo = iter.next();
String packageName = packageinfo.packageName;
if (packageName.equals(context.getPackageName())) {
Log.i(TAG, packageinfo.signatures[0].toCharsString());
return packageinfo.signatures[0].toCharsString();
}
}
return null;
}
public void getSingInfo(String pkgName) {
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
Signature sign = signs[0];
parseSignature(sign.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
}
public void parseSignature(byte[] signature) {
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
String pubKey = cert.getPublicKey().toString();
String signNumber = cert.getSerialNumber().toString();
System.out.println("signName:" + cert.getSigAlgName());
System.out.println("pubKey:" + pubKey);
System.out.println("signNumber:" + signNumber);
System.out.println("subjectDN:"+cert.getSubjectDN().toString());
} catch (CertificateException e) {
e.printStackTrace();
}
}
}
http://blog.csdn.net/wulianghuan/article/details/18400581
应各位网友的要求和反应,反射调用android.content.pm.PackageParser类函数在android5.0以上系统会出现崩溃,原因是:android5.0以上android.content.pm.PackageParser的构造函数已经改变了,新的解决方法如下,我自己测试android 5.0 android6.0手机通过:
另外大家如果存在什么问题请留言,关注度高的问题我会找时间回复和解决。
package com.yunshouhu.loaddex;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
@SuppressLint("NewApi")
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void getAPKSign(View view) {
Signature[] signatures;
if(Build.VERSION.SDK_INT>=21)
{
signatures=showUninstallAPKSignaturesAfter21("/mnt/sdcard/qqemail.apk");
}else{
signatures=showUninstallAPKSignatures("/mnt/sdcard/qqemail.apk");
}
parseSignature(signatures[0].toByteArray());
getSingInfo("com.android.phone");
}
//反射调用android.content.pm.PackageParser的时候注意:android 4.4以下是有参构造 android5.0以上是无参构造函数了。
//下面是android5.0以上的解决方法
public Signature[] showUninstallAPKSignaturesAfter21(String apkPath) {
String PATH_PackageParser = "android.content.pm.PackageParser";
try {
// PackageParser packageParser = new PackageParser();
Class pkgParserCls = Class.forName(PATH_PackageParser);
Constructor pkgParserCt = pkgParserCls.getConstructor( new Class[]{});
Object pkgParser = pkgParserCt.newInstance(new Object[]{});
Log.i(TAG, "pkgParser:" + pkgParser.toString());
// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
//方法原型: public Package parsePackage(File packageFile, int flags) throws PackageParserException
Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
"parsePackage", new Class[]{File.class,int.class});
Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
new Object[]{new File(apkPath),PackageManager.GET_SIGNATURES});
Method pkgParser_collectCertificatesMtd = pkgParserCls
.getDeclaredMethod("collectCertificates", new Class[]{ pkgParserPkg.getClass(),Integer.TYPE});
pkgParser_collectCertificatesMtd.invoke(pkgParser, new Object[]{pkgParserPkg,PackageManager.GET_SIGNATURES});
// 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
Log.i(TAG, info[0].toCharsString());
return info;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//反射调用android.content.pm.PackageParser的时候注意:android 4.4以下是有参构造 android5.0以上是无参构造函数了。
//下面是android5.0以下的解决方法
public Signature[] showUninstallAPKSignatures(String apkPath) {
String PATH_PackageParser = "android.content.pm.PackageParser";
try {
// apk包的文件路径
// 这是一个Package 解释器, 是隐藏的
// 构造函数的参数只有一个, apk文件的路径
// PackageParser packageParser = new PackageParser(apkPath);
Class pkgParserCls = Class.forName(PATH_PackageParser);
Constructor pkgParserCt = pkgParserCls.getConstructor( new Class[]{String.class});
Object pkgParser = pkgParserCt.newInstance(new Object[]{apkPath});
Log.i(TAG, "pkgParser:" + pkgParser.toString());
// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
//PackageParser.Package mPkgInfo = public Package parsePackage(File sourceFile, String destCodePath,DisplayMetrics metrics, int flags)
Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
"parsePackage", new Class[]{File.class, String.class,DisplayMetrics.class,Integer.TYPE});
Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
new Object[]{new File(apkPath), apkPath,metrics,PackageManager.GET_SIGNATURES});
Method pkgParser_collectCertificatesMtd = pkgParserCls
.getDeclaredMethod("collectCertificates", new Class[]{ pkgParserPkg.getClass(),Integer.TYPE});
pkgParser_collectCertificatesMtd.invoke(pkgParser, new Object[]{pkgParserPkg,PackageManager.GET_SIGNATURES});
// 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
Log.i(TAG, info[0].toCharsString());
return info;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getSign(Context context) {
PackageManager pm = context.getPackageManager();
List<PackageInfo> apps = pm
.getInstalledPackages(PackageManager.GET_SIGNATURES);
Iterator<PackageInfo> iter = apps.iterator();
while (iter.hasNext()) {
PackageInfo packageinfo = iter.next();
String packageName = packageinfo.packageName;
if (packageName.equals(context.getPackageName())) {
Log.i(TAG, packageinfo.signatures[0].toCharsString());
return packageinfo.signatures[0].toCharsString();
}
}
return null;
}
public void getSingInfo(String pkgName) {
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
Signature sign = signs[0];
parseSignature(sign.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
}
public void parseSignature(byte[] signature) {
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
String pubKey = cert.getPublicKey().toString();
String signNumber = cert.getSerialNumber().toString();
System.out.println("signName:" + cert.getSigAlgName());
System.out.println("pubKey:" + pubKey);
System.out.println("signNumber:" + signNumber);
System.out.println("subjectDN:"+cert.getSubjectDN().toString());
} catch (CertificateException e) {
e.printStackTrace();
}
}
}