PackageManagerCompat.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package com.emato.ich.update;
  2. import android.app.Activity;
  3. import android.app.AlarmManager;
  4. import android.app.PendingIntent;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.pm.PackageInstaller;
  8. import android.content.pm.PackageManager;
  9. import android.net.Uri;
  10. import android.os.Build;
  11. import com.emato.ich.utils.Log;
  12. import androidx.annotation.NonNull;
  13. import androidx.annotation.RequiresApi;
  14. import com.emato.ich.MainActivity;
  15. import com.emato.ich.utils.LoggingUtils;
  16. import com.emato.ich.utils.StringUtils;
  17. import com.xuexiang.xupdate.entity.DownloadEntity;
  18. import com.xuexiang.xupdate.listener.OnInstallListener;
  19. import org.jetbrains.annotations.NotNull;
  20. import java.io.BufferedReader;
  21. import java.io.Closeable;
  22. import java.io.DataOutputStream;
  23. import java.io.File;
  24. import java.io.FileInputStream;
  25. import java.io.IOException;
  26. import java.io.InputStream;
  27. import java.io.InputStreamReader;
  28. import java.io.OutputStream;
  29. import java.text.DateFormat;
  30. import java.text.SimpleDateFormat;
  31. import java.util.Date;
  32. import java.util.concurrent.atomic.AtomicBoolean;
  33. public class PackageManagerCompat implements OnInstallListener {
  34. private static final String TAG = PackageManagerCompat.class.getName();
  35. /*public static void install(Activity activity, File apkFile, OnInstallListener listener){
  36. try{
  37. Intent intent =new Intent();
  38. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  39. //Uri uri = Uri.fromFile(apkFile);
  40. Uri uri = null;
  41. //todo N FileProvider
  42. //todo O install permission
  43. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
  44. uri = androidx.core.content.FileProvider.getUriForFile(activity,activity.getPackageName()+".fileprovider", apkFile);
  45. intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
  46. intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  47. }else{
  48. uri = Uri.fromFile(apkFile);
  49. }
  50. intent.setDataAndType(uri, "application/vnd.android.package-archive");
  51. activity.startActivity(intent);
  52. listener.onInstallSuccess();
  53. } catch (Exception e) {
  54. listener.onInstallException(e);
  55. }
  56. }*/
  57. @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  58. public static void install(Context context, String apkFilePath, PackageManager packageManager, InstallListener listener) {
  59. try {
  60. Log.i(TAG, "install: 应用程序开始安装! " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  61. File apkFile = new File(apkFilePath);
  62. if (!apkFile.exists()) {
  63. throw new RuntimeException("文件不存在! 更新失败! ");
  64. }
  65. PackageInstaller packageInstaller = packageManager.getPackageInstaller();
  66. PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
  67. sessionParams.setSize(apkFile.length());
  68. int sessionId = createSession(packageInstaller, sessionParams);
  69. if (sessionId != -1) {
  70. boolean copySuccess = copyInstallFile(packageInstaller, sessionId, apkFilePath, listener);
  71. if (copySuccess) {
  72. execInstallCommand(context, packageInstaller, sessionId, listener);
  73. }
  74. }
  75. Log.i(TAG, "install: 应用程序安装完成! " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  76. } catch (Exception e) {
  77. listener.onInstallException(e);
  78. }
  79. }
  80. @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  81. private static int createSession(PackageInstaller packageInstaller,
  82. PackageInstaller.SessionParams sessionParams) {
  83. int sessionId = -1;
  84. try {
  85. sessionId = packageInstaller.createSession(sessionParams);
  86. } catch (IOException e) {
  87. e.printStackTrace();
  88. }
  89. return sessionId;
  90. }
  91. @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  92. private static boolean copyInstallFile(PackageInstaller packageInstaller,
  93. int sessionId, String apkFilePath, InstallListener listener) {
  94. InputStream in = null;
  95. OutputStream out = null;
  96. PackageInstaller.Session session = null;
  97. boolean success = false;
  98. try {
  99. File apkFile = new File(apkFilePath);
  100. session = packageInstaller.openSession(sessionId);
  101. out = session.openWrite("base.apk", 0, apkFile.length());
  102. in = new FileInputStream(apkFile);
  103. int total = 0, c;
  104. byte[] buffer = new byte[65536];
  105. while ((c = in.read(buffer)) != -1) {
  106. total += c;
  107. out.write(buffer, 0, c);
  108. }
  109. session.fsync(out);
  110. success = true;
  111. } catch (IOException e) {
  112. listener.onInstallException(e);
  113. } finally {
  114. closeQuietly(out, listener);
  115. closeQuietly(in, listener);
  116. closeQuietly(session, listener);
  117. }
  118. return success;
  119. }
  120. @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  121. private static void execInstallCommand(Context context, PackageInstaller packageInstaller, int sessionId, InstallListener listener) {
  122. PackageInstaller.Session session = null;
  123. try {
  124. session = packageInstaller.openSession(sessionId);
  125. Intent intent = new Intent(context, InstallResultReceiver.class);
  126. PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  127. session.commit(pendingIntent.getIntentSender());
  128. listener.onInstallSuccess();
  129. } catch (IOException e) {
  130. listener.onInstallException(e);
  131. } finally {
  132. closeQuietly(session, listener);
  133. }
  134. }
  135. private static void closeQuietly(Closeable c, InstallListener listener) {
  136. if (c != null) {
  137. try {
  138. c.close();
  139. } catch (IOException ignored) {
  140. listener.onInstallException(ignored);
  141. }
  142. }
  143. }
  144. /**
  145. * 重启
  146. * @param context 应用上下文
  147. */
  148. public static void restartApp(Context context) {
  149. Log.i(TAG, "restartApp: 应用程序重启中! 日期=====>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  150. try {
  151. Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
  152. if (intent != null && !StringUtils.isNullOrEmpty(intent.getAction()) && intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")) {
  153. Intent intent1 = new Intent(context, MainActivity.class);
  154. intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  155. context.startActivity(intent1);
  156. Log.i(TAG, "restartApp: ======================================>重启成功");
  157. }
  158. } catch (Exception e) {
  159. Log.e(TAG, "restartApp: ======================================>重启失败! ", e);
  160. LoggingUtils.sendErrorLog("业务异常: ======================================>重启失败! ", e);
  161. }
  162. // PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
  163. // AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  164. // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
  165. // mgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent);
  166. //
  167. // } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
  168. // mgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent);
  169. // }
  170. Log.i(TAG, "restartApp: 应用程序重启完成! 日期=====>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  171. }
  172. @Override
  173. public boolean onInstallApk(@NonNull @NotNull Context context, @NonNull @NotNull File apkFile, @NonNull @NotNull DownloadEntity downloadEntity) {
  174. AtomicBoolean flag = new AtomicBoolean(true);
  175. install(context, apkFile.getAbsolutePath(), context.getPackageManager(), new InstallListener(){
  176. @Override
  177. public void onInstallException(Exception e) {
  178. Log.e(TAG, "onInstallException: 安装失败! ", e);
  179. flag.set(false);
  180. }
  181. @Override
  182. public void onInstallSuccess() {
  183. restartApp(context);
  184. }
  185. });
  186. return flag.get();
  187. }
  188. @Override
  189. public void onInstallApkSuccess() {
  190. Log.i(TAG, "onInstallApkSuccess: 安装成功! ");
  191. }
  192. }