Files
assistant-android/app/src/main/java/com/gh/common/util/PackageUtils.java
kehaoyuan 6bf40ca237 修复同一个包存在多个更新的问题
修复已安装列表出现下载按钮问题
版主修改标签增加默认标签
2018-12-26 17:34:44 +08:00

406 lines
16 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.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import com.g00fy2.versioncompare.Version;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.lightgame.utils.Utils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.File;
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}";
/*
* 判断是否可以更新只判断gh_version的大小
*/
public static List<GameUpdateEntity> isCanUpdate(Context context, GameEntity gameEntity) {
List<GameUpdateEntity> updateList = new ArrayList<>();
boolean isAPluginGame = false;
for (ApkEntity apkEntity : gameEntity.getApk()) {
// 判断是否gh_version是否存在
String gh_version = (String) PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_version");
Object gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
if (gh_version != null && apkEntity.getGhVersion() != null && gh_id != null) {
// 确定这是一个插件游戏
if (!isAPluginGame) isAPluginGame = true;
gh_version = gh_version.substring(2);
if (Long.parseLong(gh_version) < Long.parseLong(apkEntity.getGhVersion()) && apkEntity.getForce()
&& gh_id.equals(gameEntity.getId())) {
GameUpdateEntity updateEntity = new GameUpdateEntity();
updateEntity.setId(gameEntity.getId());
updateEntity.setName(gameEntity.getName());
updateEntity.setIcon(gameEntity.getIcon());
updateEntity.setPackageName(apkEntity.getPackageName());
updateEntity.setSize(apkEntity.getSize());
updateEntity.setVersion(apkEntity.getVersion());
updateEntity.setGhVersion(apkEntity.getGhVersion());
updateEntity.setUrl(apkEntity.getUrl());
updateEntity.setPlatform(apkEntity.getPlatform());
updateEntity.setEtag(apkEntity.getEtag());
updateEntity.setBrief(gameEntity.getBrief());
updateEntity.setTag(gameEntity.getTag());
updateList.add(updateEntity);
}
}
}
// 不是插件游戏
if (!isAPluginGame) {
for (ApkEntity apkEntity : gameEntity.getApkNormal()) {
String versionFromRequest = apkEntity.getVersion();
String versionFromInstalledApp = getVersionByPackage(context, apkEntity.getPackageName());
// 是否需要显示更新
boolean shouldShouldUpdate = apkEntity.getForce();
if (shouldShouldUpdate && !TextUtils.isEmpty(versionFromRequest) && !TextUtils.isEmpty(versionFromInstalledApp)) {
// 根据版本判断是否需要更新
shouldShouldUpdate = new Version(versionFromRequest).isHigherThan(versionFromInstalledApp);
if (shouldShouldUpdate) {
GameUpdateEntity updateEntity = new GameUpdateEntity();
updateEntity.setId(gameEntity.getId());
updateEntity.setName(gameEntity.getName());
updateEntity.setIcon(gameEntity.getIcon());
updateEntity.setPackageName(apkEntity.getPackageName());
updateEntity.setSize(apkEntity.getSize());
updateEntity.setVersion(apkEntity.getVersion());
updateEntity.setGhVersion(apkEntity.getGhVersion());
updateEntity.setUrl(apkEntity.getUrl());
updateEntity.setPlatform(apkEntity.getPlatform());
updateEntity.setEtag(apkEntity.getEtag());
updateEntity.setBrief(gameEntity.getBrief());
updateEntity.setTag(gameEntity.getTag());
updateList.add(updateEntity);
}
}
}
}
return updateList;
}
/*
* 获取meta-data
*/
public static Object getMetaData(Context context, String packageName, String name) {
try {
Bundle metaDate = context.getApplicationContext().getPackageManager().getApplicationInfo(
packageName, PackageManager.GET_META_DATA).metaData;
if (metaDate != null) {
return metaDate.get(name);
}
} catch (NameNotFoundException e) {
// e.printStackTrace();
}
return null;
}
/*
* 判断是否是插件包
*/
public static boolean isSignature(Context context, String packageName) {
String signature = getApkSignatureByPackageName(context, packageName);
return publicKey.equals(signature);
}
/*
* 根据包名获取apk的签名信息
*/
public static String getApkSignatureByPackageName(Context context, String packageName) {
try {
PackageInfo packageInfo = context.getApplicationContext().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 compareSignatureBetweenInstalledAppWithApk(Context context, String packageName, String apkFilePath) {
try {
Signature sig = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];
Signature releaseSig = context.getPackageManager().getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNATURES).signatures[0];
return sig.hashCode() == releaseSig.hashCode();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/*
* 解析签名
*/
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 void launchSetup(final Context context, final String path) {
try {
if (isCanLaunchSetup(context, path)) {
context.startActivity(PackageUtils.getInstallIntent(context, path));
} else {
DialogUtils.showPluginDialog(context,
() -> context.startActivity(PackageUtils.getUninstallIntent(context, path)));
}
} catch (Exception e) {
Utils.toast(context, e.getMessage());
}
}
/*
* 根据apk路径获取apk包名、签名 根据包名 判断 是否已安装游戏 根据签名 判断 是否一致
*/
public static boolean isCanLaunchSetup(Context context, String path) {
String packageName = getPackageNameByPath(context, path);
if (TextUtils.isEmpty(packageName)) {
return true;
}
boolean isContain = com.gh.gamecenter.manager.PackagesManager.INSTANCE.isInstalled(packageName);
if (!isContain) {
return true;
}
boolean isInstalled = isInstalled(context, packageName);
if (!isInstalled) {
return true;
}
// 由于新增了非插件的也能更新的功能,倘若两个签名一样的话就不走下面的光环签名判断了
if (compareSignatureBetweenInstalledAppWithApk(context, packageName, path)) {
return true;
}
String signature = getApkSignatureByPackageName(context, packageName);
return publicKey.equals(signature);
}
/*
* 根据路径,获取安装游戏的意图
*/
public static Intent getInstallIntent(Context context, String path) {
Uri uri = Uri.fromFile(new File(path));
Intent installIntent = new Intent(Intent.ACTION_VIEW);
if ("smartisan".equals(Build.MANUFACTURER)) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, new File(path));
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
}
InstallUtils.getInstance(context).addInstall(getPackageNameByPath(context, path));
return installIntent;
}
/*
* 根据包名,获取卸载游戏的意图
*/
public static Intent getUninstallIntent(Context context, String path) {
Intent uninstallIntent = new Intent();
uninstallIntent.setAction(Intent.ACTION_DELETE);
uninstallIntent.addCategory(Intent.CATEGORY_DEFAULT);
String packageName = getPackageNameByPath(context, path);
uninstallIntent.setData(Uri.parse("package:" + packageName));
InstallUtils.getInstance(context).addUninstall(packageName);
return uninstallIntent;
}
/*
* 根据路径获取apk的包名
*/
public static String getPackageNameByPath(Context context, String path) {
PackageManager packageManager = context.getApplicationContext().getPackageManager();
PackageInfo info = packageManager.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
if (info != null) {
ApplicationInfo appInfo = info.applicationInfo;
return appInfo.packageName;
}
return null;
}
/*
* 根据包名,判断是否已安装该游戏
*/
public static boolean isInstalled(Context context, String packageName) {
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
return intent != null;
}
/*
* 获取应用第一次安装的时间
*/
public static long getInstalledTime(Context context, String packageName) {
try {
if (context == null) return 0;
PackageInfo packageInfo = context.getApplicationContext().getPackageManager()
.getPackageInfo(packageName, 0);
return packageInfo.firstInstallTime;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return 0;
}
/*
* 返回光环助手的版本信息
*/
public static String getVersionName() {
return BuildConfig.VERSION_NAME;
}
/*
* 返回光环助手的版本code
*/
public static int getVersionCode() {
return BuildConfig.VERSION_CODE;
}
/*
* 获取apk的版本
*/
public static String getVersionByPackage(Context context, String packageName) {
try {
return context.getApplicationContext().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/*
* 获取apk的版本
*/
public static Drawable getIconByPackage(Context context, String packageName) {
try {
PackageManager packageManager = context.getApplicationContext().getPackageManager();
return packageManager.getApplicationIcon(packageName);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/*
* 获取所有已安装的软件的包名、版本(非系统应用)
*/
public static ArrayList<String> getAllPackageName(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = context.getApplicationContext().getPackageManager().getInstalledPackages(0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
list.add(packageInfo.packageName);
}
}
}
return list;
}
public static JSONArray getAppList(Context context) {
JSONArray jsonArray = new JSONArray();
try {
PackageManager pm = context.getPackageManager();
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", pm.getApplicationLabel(packageInfo.applicationInfo).toString());
jsonObject.put("package", packageInfo.packageName);
jsonObject.put("version", packageInfo.versionName);
jsonArray.put(jsonObject);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return jsonArray;
}
/*
* 启动应用
*/
public static void launchApplicationByPackageName(Context context, String packageName) {
try {
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
if (intent != null) {
context.startActivity(intent);
} else {
Utils.toast(context, "启动失败");
}
} catch (Exception e) {
e.printStackTrace();
Utils.toast(context, "启动失败");
}
}
/*
* 根据包名,获取软件名称
*/
public static String getNameByPackageName(Context context, String packageName) {
try {
PackageManager pm = context.getApplicationContext().getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(
packageName, 0);
return applicationInfo.loadLabel(pm).toString();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
}