UpdateTool.java 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package xn.update;
  2. import android.annotation.SuppressLint;
  3. import android.app.DownloadManager;
  4. import android.content.BroadcastReceiver;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.IntentFilter;
  8. import android.content.pm.ApplicationInfo;
  9. import android.content.pm.PackageInfo;
  10. import android.content.pm.PackageManager;
  11. import android.net.Uri;
  12. import android.os.AsyncTask;
  13. import android.os.Environment;
  14. import android.util.Log;
  15. import com.blankj.utilcode.util.AppUtils;
  16. import com.blankj.utilcode.util.FileUtils;
  17. import com.blankj.utilcode.util.GsonUtils;
  18. import com.blankj.utilcode.util.LogUtils;
  19. import com.blankj.utilcode.util.SPUtils;
  20. import com.blankj.utilcode.util.ThreadUtils;
  21. import org.json.JSONException;
  22. import java.io.File;
  23. import java.io.IOException;
  24. import java.util.List;
  25. import java.util.concurrent.atomic.AtomicBoolean;
  26. import okhttp3.Response;
  27. import xn.update.constant.AppConstant;
  28. import xn.update.http.HttpTool;
  29. import xn.update.http.bean.response.UpdateTask;
  30. public enum UpdateTool {
  31. INSTANCE;
  32. private UpdateTask.Task task;
  33. @SuppressLint("SdCardPath")
  34. private final String apkPath = "/sdcard/Download/apk/";
  35. private final String apkName = "app.apk";
  36. private DownloadManager downloadManager;
  37. private long downloadId;
  38. private long lastRunTime;
  39. private final AtomicBoolean isUploading = new AtomicBoolean(false);
  40. public void checkUpdate(Context context) {
  41. // 若是3分钟都没下载完成,则认为下载失败
  42. long runTime = (System.currentTimeMillis() - lastRunTime);
  43. if (lastRunTime > 0 && runTime > 1000 * 60 * 3) {
  44. isUploading.set(false);
  45. }
  46. // 空闲中
  47. if (!isUploading.get() && SPUtils.getInstance().getBoolean(AppConstant.AUTO_UPDATE, true)) {
  48. lastRunTime = System.currentTimeMillis();
  49. isUploading.set(true);
  50. if (null == downloadManager) {
  51. downloadManager = (DownloadManager) context.getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
  52. }
  53. ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<Boolean>() {
  54. @SuppressLint({"UnspecifiedRegisterReceiverFlag", "SdCardPath"})
  55. @Override
  56. public Boolean doInBackground() throws Throwable {
  57. try {
  58. Response response = HttpTool.INSTANCE.update();
  59. if (response.isSuccessful()) {
  60. String json = response.body().string();
  61. UpdateTask updateTask = GsonUtils.fromJson(json, UpdateTask.class);
  62. if (updateTask.getCode() == 200) {
  63. List<UpdateTask.Task> updateTaskData = updateTask.getData();
  64. if (null != updateTaskData && !updateTaskData.isEmpty()) {
  65. task = updateTaskData.get(0);
  66. FileUtils.createOrExistsDir(apkPath);
  67. FileUtils.deleteAllInDir(apkPath);
  68. if (!AppUtils.getAppPackageName().equals(task.getStartLaunchPackage())) {
  69. SPUtils.getInstance().put(AppConstant.KeySP.MASTER_PACKAGE_NAME, task.getStartLaunchPackage());
  70. }
  71. DownloadManager.Request request = new DownloadManager.Request(Uri.parse(Tool.INSTANCE.checkUrl(task.getApkUrl())));
  72. request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "apk/" + apkName);
  73. request.setMimeType("application/vnd.android.package-archive");
  74. request.setVisibleInDownloadsUi(false);
  75. request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
  76. context.registerReceiver(downloadApkReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
  77. downloadId = downloadManager.enqueue(request);
  78. LogUtils.d("发起下载", downloadId);
  79. return true;
  80. }
  81. } else {
  82. LogUtils.e(updateTask.getMessage());
  83. }
  84. }
  85. } catch (Exception e) {
  86. LogUtils.e(Log.getStackTraceString(e));
  87. }
  88. return false;
  89. }
  90. @Override
  91. public void onSuccess(Boolean result) {
  92. isUploading.set(result);
  93. }
  94. });
  95. } else {
  96. LogUtils.d("正在升级中...");
  97. }
  98. }
  99. private final BroadcastReceiver downloadApkReceiver = new BroadcastReceiver() {
  100. @Override
  101. public void onReceive(Context context, Intent intent) {
  102. long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
  103. LogUtils.d("下载成功", downloadId, task);
  104. if (downloadId == id) {
  105. if (null != task) {
  106. AsyncTask.execute(() -> {
  107. try {
  108. HttpTool.INSTANCE.updateCallBack(task.getTaskId(), task.getDeviceCode(), true, false);
  109. } catch (IOException | JSONException e) {
  110. LogUtils.e(Log.getStackTraceString(e));
  111. }
  112. // 升级其它App
  113. if (!task.getStartLaunchPackage().equals(AppUtils.getAppPackageName())) {
  114. Tool.INSTANCE.cmd("pm uninstall" + task.getStartLaunchPackage());
  115. } else {
  116. SPUtils.getInstance().put("isSelfUpdate", true, true);
  117. SPUtils.getInstance().put("SelfUpdate", GsonUtils.toJson(task), true);
  118. }
  119. Tool.INSTANCE.cmd("pm install -d -g " + apkPath + apkName);
  120. Tool.INSTANCE.openApp(task.getStartLaunchPackage());
  121. try {
  122. HttpTool.INSTANCE.updateCallBack(task.getTaskId(), task.getDeviceCode(), true, true);
  123. } catch (IOException | JSONException e) {
  124. LogUtils.e(Log.getStackTraceString(e));
  125. }
  126. isUploading.set(false);
  127. });
  128. }
  129. }
  130. }
  131. };
  132. /**
  133. * 解析未安装的APK文件
  134. *
  135. * @param context 上下文
  136. * @param apkPath APK文件路径
  137. */
  138. public void parseApkFile(Context context, String apkPath) {
  139. PackageManager pm = context.getPackageManager();
  140. PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath,
  141. PackageManager.GET_PERMISSIONS | PackageManager.GET_META_DATA);
  142. if (packageInfo != null) {
  143. // 获取应用信息
  144. ApplicationInfo appInfo = packageInfo.applicationInfo;
  145. // 修复资源路径问题
  146. appInfo.sourceDir = apkPath;
  147. appInfo.publicSourceDir = apkPath;
  148. // 获取基本信息
  149. String packageName = packageInfo.packageName;
  150. String versionName = packageInfo.versionName;
  151. int versionCode = packageInfo.versionCode;
  152. // 获取权限
  153. String[] permissions = packageInfo.requestedPermissions;
  154. // 获取APK大小
  155. File apkFile = new File(apkPath);
  156. long apkSize = apkFile.length();
  157. // 打印信息
  158. Log.d("APK-INFO", "包名: " + packageName);
  159. Log.d("APK-INFO", "版本: " + versionName + "(" + versionCode + ")");
  160. Log.d("APK-INFO", "大小: " + (apkSize / 1024) + "KB");
  161. if (permissions != null) {
  162. for (String perm : permissions) {
  163. Log.d("APK-INFO", "权限: " + perm);
  164. }
  165. }
  166. }
  167. }
  168. }