|
|
@@ -11,8 +11,16 @@ import android.graphics.drawable.Drawable;
|
|
|
import android.net.Uri;
|
|
|
import android.text.TextUtils;
|
|
|
import android.util.Base64;
|
|
|
-
|
|
|
+import android.view.View;
|
|
|
+
|
|
|
+import com.sheep.gamegroup.model.entity.ApkFileInfo;
|
|
|
+import com.sheep.gamegroup.model.entity.DialogConfig;
|
|
|
+import com.sheep.gamegroup.util.ActivityManager;
|
|
|
+import com.sheep.gamegroup.util.DataKey;
|
|
|
+import com.sheep.gamegroup.util.DataUtil;
|
|
|
+import com.sheep.gamegroup.util.ViewUtil;
|
|
|
import com.sheep.jiuyan.samllsheep.SheepApp;
|
|
|
+import com.sheep.jiuyan.samllsheep.utils.G;
|
|
|
import com.sheep.jiuyan.samllsheep.utils.PackageUtil;
|
|
|
|
|
|
import java.security.MessageDigest;
|
|
|
@@ -22,6 +30,13 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.UUID;
|
|
|
|
|
|
+import rx.Observable;
|
|
|
+import rx.Subscriber;
|
|
|
+import rx.android.schedulers.AndroidSchedulers;
|
|
|
+import rx.functions.Action1;
|
|
|
+import rx.functions.Func1;
|
|
|
+import rx.schedulers.Schedulers;
|
|
|
+
|
|
|
/**
|
|
|
* apk helper
|
|
|
* <p>
|
|
|
@@ -47,6 +62,7 @@ public class ApkUtils {
|
|
|
installedApkContainer = null;
|
|
|
|
|
|
}
|
|
|
+
|
|
|
private void setInstalledApkContainer() {
|
|
|
installedApkContainer = getInstalledApks(SheepApp.getInstance());
|
|
|
|
|
|
@@ -77,22 +93,153 @@ public class ApkUtils {
|
|
|
* @param context Context
|
|
|
* @param apkPath apkPath
|
|
|
*/
|
|
|
- public static final void installApk(Context context, String apkPath) {
|
|
|
- if(TextUtils.isEmpty(apkPath)){
|
|
|
-// G.showToast(R.string.unknown_error);
|
|
|
- return;
|
|
|
+ public static final void installApk(final Context context, final String apkPath) {
|
|
|
+ final ApkFileInfo apkFileInfo = new ApkFileInfo();
|
|
|
+ apkFileInfo.setPath(apkPath);
|
|
|
+ Observable.just(apkFileInfo)
|
|
|
+ .filter(new Func1<ApkFileInfo, Boolean>() {
|
|
|
+ @Override
|
|
|
+ public Boolean call(ApkFileInfo item) {
|
|
|
+ return !TextUtils.isEmpty(item.getPath());
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(new Func1<ApkFileInfo, Boolean>() {
|
|
|
+ @Override
|
|
|
+ public Boolean call(ApkFileInfo item) {
|
|
|
+ return item.existsPath();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(new Func1<ApkFileInfo, Boolean>() {
|
|
|
+ @Override
|
|
|
+ public Boolean call(ApkFileInfo item) {
|
|
|
+ return !TextUtils.isEmpty(item.initPackageNameFromPath(context).getPackageName());
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(new Func1<ApkFileInfo, Boolean>() {
|
|
|
+ @Override
|
|
|
+ public Boolean call(ApkFileInfo item) {
|
|
|
+ //已经安装且签名的md5相同,文件与安装应用的md5也相同,则过滤掉
|
|
|
+ return !(item.checkInstall(context) && item.checkApkAndFileSignMd5() && item.checkApkAndFileMd5());
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .subscribeOn(Schedulers.io())
|
|
|
+ .observeOn(AndroidSchedulers.mainThread())
|
|
|
+ .subscribe(new Subscriber<ApkFileInfo>() {
|
|
|
+ private boolean doneNext;
|
|
|
+ @Override
|
|
|
+ public void onCompleted() {
|
|
|
+ if(doneNext)
|
|
|
+ return;
|
|
|
+ if(apkFileInfo.isAppInstalled()){//在onNext中未处理且应用已经安装的情况下,直接打开应用
|
|
|
+ PackageUtil.startApp(context, apkFileInfo.getPackageName());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ G.showToast("无需安装");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(Throwable e) {
|
|
|
+ G.showToast(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onNext(final ApkFileInfo item) {
|
|
|
+ doneNext = true;
|
|
|
+ if (!item.isAppInstalled() || (item.isEqualsSignMd5() && item.isCanInstallVersion())) {
|
|
|
+ PackageUtil.installApk(context, item.getPath());
|
|
|
+ DataUtil.putAsString(DataKey.KEY_INSTALL_APK_PACKAGE_NAME, item.getPackageName());
|
|
|
+ } else {//签名不同,则提示卸载
|
|
|
+ ViewUtil.showMsgDialog(ActivityManager.getInstance().currentActivity(), new DialogConfig()
|
|
|
+ .setTitle("提示").setMsg("需要卸载当前应用才能继续安装,是否继续").setBtnLeftText("不用了")
|
|
|
+ .setBtnRightText("继续").setBtnRightOnClickListener(new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View view) {
|
|
|
+ //这里卸载后 没法继续,需要在接收卸载广播的地方进行安装操作
|
|
|
+ DataUtil.putAsString(DataKey.KEY_WILL_INSTALL_APK_PATH, item.getPath());
|
|
|
+ DataUtil.putAsString(DataKey.KEY_WILL_INSTALL_APK_PACKAGE_NAME, item.getPackageName());
|
|
|
+ uninstallApk(SheepApp.getInstance(), item.getPackageName());
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * MD5加密
|
|
|
+ *
|
|
|
+ * @param byteStr 需要加密的内容
|
|
|
+ * @return 返回 byteStr的md5值
|
|
|
+ */
|
|
|
+ public static String encryptionMD5(byte[] byteStr) {
|
|
|
+ MessageDigest messageDigest;
|
|
|
+ StringBuilder md5Sb = new StringBuilder();
|
|
|
+ try {
|
|
|
+ messageDigest = MessageDigest.getInstance("MD5");
|
|
|
+ messageDigest.reset();
|
|
|
+ messageDigest.update(byteStr);
|
|
|
+ byte[] byteArray = messageDigest.digest();
|
|
|
+// return Base64.encodeToString(byteArray,Base64.NO_WRAP);
|
|
|
+ for (int i = 0; i < byteArray.length; i++) {
|
|
|
+ if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) {
|
|
|
+ md5Sb.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
|
|
|
+ } else {
|
|
|
+ md5Sb.append(Integer.toHexString(0xFF & byteArray[i]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
|
+ return md5Sb.toString();
|
|
|
+ }
|
|
|
|
|
|
- PackageUtil.installApk(context, apkPath);
|
|
|
+ /**
|
|
|
+ * 获取app签名md5值
|
|
|
+ */
|
|
|
+ public static String getApkSignMd5StrByPackageName(String packageName, Action1<PackageInfo> action1) {
|
|
|
+ try {
|
|
|
+ PackageInfo packageInfo = SheepApp.getInstance().getPackageManager().getPackageInfo(
|
|
|
+ packageName, PackageManager.GET_ACTIVITIES | PackageManager.GET_SIGNATURES);
|
|
|
+ Signature[] signs = packageInfo.signatures;
|
|
|
+ Signature sign = signs[0];
|
|
|
+ String signStr = encryptionMD5(sign.toByteArray());
|
|
|
+ if (action1 != null)
|
|
|
+ action1.call(packageInfo);
|
|
|
+ return signStr;
|
|
|
+ } catch (PackageManager.NameNotFoundException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (Exception e2) {
|
|
|
+ e2.printStackTrace();
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
|
|
|
- /*
|
|
|
- 设置包名
|
|
|
- */
|
|
|
- SheepApp.getInstance()
|
|
|
- .setPackgeName(
|
|
|
- getUnInstallApkPackageName(context, apkPath));
|
|
|
+ /**
|
|
|
+ * 获取未安装app签名md5值
|
|
|
+ */
|
|
|
+ public static String getApkSignMd5StrByPath(String apkPath, Action1<PackageInfo> action1) {
|
|
|
+ try {
|
|
|
+ PackageInfo packageInfo = SheepApp.getInstance().getPackageManager().getPackageArchiveInfo(
|
|
|
+ apkPath, PackageManager.GET_ACTIVITIES | PackageManager.GET_SIGNATURES);
|
|
|
+ Signature[] signs = packageInfo.signatures;
|
|
|
+ Signature sign = signs[0];
|
|
|
+ String signStr = encryptionMD5(sign.toByteArray());
|
|
|
+ if (action1 != null)
|
|
|
+ action1.call(packageInfo);
|
|
|
+ return signStr;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return "";
|
|
|
}
|
|
|
|
|
|
+ /* 卸载apk */
|
|
|
+ public static void uninstallApk(Context context, String packageName) {
|
|
|
+ Uri uri = Uri.parse("package:" + packageName);
|
|
|
+ Intent intent = new Intent(Intent.ACTION_DELETE, uri);
|
|
|
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
+ context.startActivity(intent);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* get alll installed apks
|
|
|
@@ -116,8 +263,6 @@ public class ApkUtils {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Open a application by packagename
|
|
|
*
|
|
|
@@ -179,7 +324,7 @@ public class ApkUtils {
|
|
|
setInstalledApkContainer();
|
|
|
}
|
|
|
PackageInfo pkg = installedApkContainer.get(packageName);
|
|
|
- if(null == pkg){
|
|
|
+ if (null == pkg) {
|
|
|
return EQUALS;
|
|
|
}
|
|
|
if (pkg.versionCode == versionCode) {
|
|
|
@@ -286,6 +431,7 @@ public class ApkUtils {
|
|
|
return "0.0.0";
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
public static PackageInfo getPackageInfo(String packageName) {
|
|
|
try {
|
|
|
PackageManager pm = SheepApp.getInstance().getPackageManager();
|
|
|
@@ -308,7 +454,7 @@ public class ApkUtils {
|
|
|
}
|
|
|
|
|
|
|
|
|
- public static void invokeBroswer(Context context ,String targetUrl){
|
|
|
+ public static void invokeBroswer(Context context, String targetUrl) {
|
|
|
Uri uri = Uri.parse(targetUrl);
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
intent.setData(uri);
|