Files
assistant-android/app/src/main/java/com/gh/common/util/PackageUtils.java
huangzhuanghua 47914f94ac 修复部分bug
2016-09-29 18:32:55 +08:00

360 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.gh.common.util;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.widget.Toast;
import com.gh.gamecenter.manager.FilterManager;
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.ArrayList;
import java.util.List;
public class PackageUtils {
public static final String publicKey = "OpenSSLRSAPublicKey{modulus=a8c4bb5748fec8d5c35db1a7a182d41ba4721a91131a417330af79ef4ddb43f9fa0ff4907b0a613bfe152de0ed8fc1b2e6f94a908aa98a5f7adc1ce814ba7ec919d75d9910bdfd8649b4789da6a90ffb61f0d23ac4f828a78fcd0d6f6120c1c43c1f87f7498a89eb40ca8e32dfc2f9d5c10d612b95192870223674e241e53305abf320d7eed76ded398778576e4db7b17b3bc6a792f13de5e43a6a5fae4276c73e6990ce97f68dff0ec16fc9594f175c8d49cd0d7877340d9de60942ca0efc737e50b6c295dfe0713e4532b4e810e1ea11b702b4a27753e41559cbceb247e7f044ec4e3ab2e8bccd8b9fd71286e63307550bcde86deee95adb8133076269135b,publicExponent=10001}";
/*
* 根据apk路径获取apk的签名信息,耗时
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static String getApkSignatureByPath(Context context, String path) {
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] = path;
Object pkgParser = pkgParserCt.newInstance(valueArgs);
// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
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(path);
valueArgs[1] = path;
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);
return parseSignature(info[0].toByteArray())[0];
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/*
* 根据路径获取apk的包名
*/
public static String getPackageNameByPath(Context context, String path) {
PackageManager packageManager = context.getPackageManager();
PackageInfo info = packageManager.getPackageArchiveInfo(path,
PackageManager.GET_ACTIVITIES);
if (info != null) {
ApplicationInfo appInfo = info.applicationInfo;
return appInfo.packageName;
}
return null;
}
public static Object getMetaData(Context context, String packageName, String name) {
try {
Bundle metaDate = context.getPackageManager().getApplicationInfo(
packageName, PackageManager.GET_META_DATA).metaData;
if (metaDate != null) {
return metaDate.get(name);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/*
* 根据包名获取apk的签名信息
*/
public static String getApkSignatureByPackageName(Context context,
String packageName) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
Signature[] signatures = packageInfo.signatures;
return parseSignature(signatures[0].toByteArray())[0];
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/*
* 判断是否是插件包
*/
public static boolean isSignature(Context context, String packageName) {
String signature = getApkSignatureByPackageName(context, packageName);
if (publicKey.equals(signature)) {
return true;
}
return false;
}
/**
* 根据apk路径获取apk包名、签名 根据包名 判断 是否已安装游戏 根据签名 判断 是否一致
*
* @param path apk路径
* @return true 可执行安装 false 要卸载已安装的,再执行安装
*/
public static boolean isCanLaunchSetup(Context context, String path) {
String packageName = getPackageNameByPath(context, path);
boolean isContain = isContain(context, packageName);
if (!isContain) {
return true;
}
boolean isInstalled = isInstalled(context, packageName);
if (!isInstalled) {
return true;
}
String signature = getApkSignatureByPackageName(context, packageName);
return publicKey.equals(signature);
}
/*
* 启动安装应用程序
*/
public static void launchSetup(final Context context, final String path) {
if (isCanLaunchSetup(context, path)) {
context.startActivity(PackageUtils.getInstallIntent(path));
} else {
DialogUtils.showPluginDialog(context, new DialogUtils.ConfiremListener() {
@Override
public void onConfirem() {
context.startActivity(PackageUtils.getUninstallIntent(context, path));
}
});
}
}
/*
* 获取应用第一次安装的时间
*/
public static long getInstalledTime(Context context, String packageName) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(packageName, 0);
return packageInfo.firstInstallTime;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return 0;
}
/*
* 解析签名
*/
private static String[] parseSignature(byte[] signature) {
String[] ret = null;
try {
CertificateFactory certFactory = CertificateFactory
.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory
.generateCertificate(new ByteArrayInputStream(signature));
ret = new String[] { cert.getPublicKey().toString(),
cert.getSerialNumber().toString() };
} catch (CertificateException e) {
e.printStackTrace();
}
return ret;
}
/*
* 返回光环助手的版本信息
*/
public static String getVersion(Context context) {
try {
PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0);
return pkgInfo.versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
public static String getVersionByPackage(Context context, String packageName) {
try {
return context.getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取所有已安装的软件的包名、版本(非系统应用)
*
* @param context
* 上下文
* @return 已安装软件的包名的集合
*/
public static ArrayList<String> getAllPackageName(Context context) {
FilterManager filterManager = new FilterManager(context);
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = context.getPackageManager().getInstalledPackages(0);
for (int i = 0, size = packageInfos.size(); i < size; i++) {
PackageInfo packageInfo = packageInfos.get(i);
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
if (!filterManager.isFilter(packageInfo.packageName)) {
list.add(packageInfo.packageName);
}
}
}
}
return list;
}
public static void launchApplicationByPackageName(Context context,
String packageName) {
Intent intent = context.getPackageManager().getLaunchIntentForPackage(
packageName);
if (intent != null) {
context.startActivity(intent);
} else {
Toast.makeText(context, "启动失败", Toast.LENGTH_SHORT).show();
}
}
/*
* 根据包名,获取软件名称
*/
public static String getNameByPackageName(Context context,
String packageName) {
try {
PackageManager pm = context.getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(
packageName, 0);
return applicationInfo.loadLabel(pm).toString();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/*
* 根据包名,判断是否已安装该游戏
*/
public static boolean isInstalled(Context context, String packageName) {
Intent intent = context.getPackageManager().getLaunchIntentForPackage(
packageName);
if (intent == null) {
return false;
}
return true;
}
private static ArrayMap<String, Boolean> map;
public static boolean isContain(Context context, String packageName) {
if (TextUtils.isEmpty(packageName)) {
return false;
}
if (map == null) {
map = new ArrayMap<>();
List<PackageInfo> infos = context.getPackageManager()
.getInstalledPackages(0);
for (PackageInfo info : infos) {
map.put(info.packageName, true);
}
}
Boolean b = map.get(packageName);
if (b != null) {
return true;
}
return false;
}
/*
* 根据包名,获取卸载游戏的意图
*/
public static Intent getUninstallIntent(Context context, String path) {
Intent uninstallIntent = new Intent();
uninstallIntent.setAction("android.intent.action.DELETE");
uninstallIntent.addCategory("android.intent.category.DEFAULT");
uninstallIntent.setData(Uri.parse("package:"
+ getPackageNameByPath(context, path)));
return uninstallIntent;
}
/*
* 根据路径,获取安装游戏的意图
*/
public static Intent getInstallIntent(String path) {
Uri uri = Uri.fromFile(new File(path));
Intent installIntent = new Intent(Intent.ACTION_VIEW);
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setDataAndType(uri,
"application/vnd.android.package-archive");
return installIntent;
}
public static String getInstalledApkPath(Context context, String packageName) {
try {
return context.getPackageManager().getApplicationInfo(packageName,
0).sourceDir;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
}