package com.emato.ich.update; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.util.Log; import androidx.annotation.RequiresApi; import java.io.BufferedReader; import java.io.Closeable; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class PackageManagerCompat { private static final String TAG = PackageManagerCompat.class.getName(); /*public static void install(Activity activity, File apkFile, OnInstallListener listener){ try{ Intent intent =new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //Uri uri = Uri.fromFile(apkFile); Uri uri = null; //todo N FileProvider //todo O install permission if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ uri = androidx.core.content.FileProvider.getUriForFile(activity,activity.getPackageName()+".fileprovider", apkFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); }else{ uri = Uri.fromFile(apkFile); } intent.setDataAndType(uri, "application/vnd.android.package-archive"); activity.startActivity(intent); listener.onInstallSuccess(); } catch (Exception e) { listener.onInstallException(e); } }*/ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public static void install(Context context, String apkFilePath, PackageManager packageManager, OnInstallListener listener) { try { Log.i(TAG, "install: 应用程序开始安装! " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); File apkFile = new File(apkFilePath); if (!apkFile.exists()) { throw new RuntimeException("文件不存在! 更新失败! "); } PackageInstaller packageInstaller = packageManager.getPackageInstaller(); PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL); sessionParams.setSize(apkFile.length()); int sessionId = createSession(packageInstaller, sessionParams); if (sessionId != -1) { boolean copySuccess = copyInstallFile(packageInstaller, sessionId, apkFilePath, listener); if (copySuccess) { execInstallCommand(context, packageInstaller, sessionId, listener); } } Log.i(TAG, "install: 应用程序安装完成! " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } catch (Exception e) { listener.onInstallException(e); } } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private static int createSession(PackageInstaller packageInstaller, PackageInstaller.SessionParams sessionParams) { int sessionId = -1; try { sessionId = packageInstaller.createSession(sessionParams); } catch (IOException e) { e.printStackTrace(); } return sessionId; } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private static boolean copyInstallFile(PackageInstaller packageInstaller, int sessionId, String apkFilePath, OnInstallListener listener) { InputStream in = null; OutputStream out = null; PackageInstaller.Session session = null; boolean success = false; try { File apkFile = new File(apkFilePath); session = packageInstaller.openSession(sessionId); out = session.openWrite("base.apk", 0, apkFile.length()); in = new FileInputStream(apkFile); int total = 0, c; byte[] buffer = new byte[65536]; while ((c = in.read(buffer)) != -1) { total += c; out.write(buffer, 0, c); } session.fsync(out); success = true; } catch (IOException e) { listener.onInstallException(e); } finally { closeQuietly(out, listener); closeQuietly(in, listener); closeQuietly(session, listener); } return success; } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private static void execInstallCommand(Context context, PackageInstaller packageInstaller, int sessionId, OnInstallListener listener) { PackageInstaller.Session session = null; try { session = packageInstaller.openSession(sessionId); Intent intent = new Intent(context, InstallResultReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); session.commit(pendingIntent.getIntentSender()); listener.onInstallSuccess(); } catch (IOException e) { listener.onInstallException(e); } finally { closeQuietly(session, listener); } } private static void closeQuietly(Closeable c, OnInstallListener listener) { if (c != null) { try { c.close(); } catch (IOException ignored) { listener.onInstallException(ignored); } } } /** * 重启 * @param context 应用上下文 */ public static void restartApp(Context context) { Log.i(TAG, "restartApp: 应用程序重启中! 日期=====>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT); AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上 mgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上 mgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent); } Log.i(TAG, "restartApp: 应用程序重启完成! 日期=====>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }