package etelligens.com.foodsafety.utils; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.Handler; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import androidx.core.content.FileProvider; import etelligens.com.foodsafety.R; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.security.SecureRandom; import java.util.regex.Matcher; import java.util.regex.Pattern; import static me.pushy.sdk.config.PushyLogging.TAG; /** * @author wj * @Description: 自动更新apk * @create 2023/10/24 14:02 **/ public class AutoUpdater { // 下载安装包的网络路径 private String apkUrl = "http://52.74.130.36/upload/app/"; protected String checkUrl = apkUrl + "output-metadata.json"; // 保存APK的文件名 private static final String saveFileName = "release.apk"; private static File apkFile; // 下载线程 private Thread downLoadThread; private int progress;// 当前进度 // 应用程序Context private Context mContext; // 是否是最新的应用,默认为false private boolean isNew = false; private boolean intercept = false; // 进度条与通知UI刷新的handler和msg常量 private ProgressBar mProgress; private TextView txtStatus; private static final int DOWN_UPDATE = 1; private static final int DOWN_OVER = 2; private static final int SHOWDOWN = 3; public AutoUpdater(Context context) { mContext = context; String root = Environment.getExternalStorageDirectory().getPath(); String parentPath = ""; try { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { parentPath = mContext.getExternalFilesDir(null).getPath(); } else { parentPath = mContext.getFilesDir().getPath(); } } catch (Exception e) { Log.d(TAG, "doDownload e:" + e.getMessage()); } Log.d(TAG, "doDownload parentPath:" + parentPath); //Toast.makeText(mContext,"跟路径"+root,Toast.LENGTH_SHORT).show(); //Toast.makeText(mContext, "Android版本"+Build.VERSION.SDK_INT, Toast.LENGTH_SHORT).show(); apkFile = new File(parentPath, saveFileName); //如果已有文件,删除 if (apkFile.exists()) { Log.d(TAG, "doDownload delete APK"); apkFile.delete(); } //Log.e("路径",mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()); //apkFile = new File(root, saveFileName); //apkFile = new File(mContext.getFilesDir(), saveFileName); } public void ShowUpdateDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setCancelable(false); builder.setTitle("SOFTWARE UPDATE"); builder.setMessage("Please download and install the latest version !"); builder.setPositiveButton("Now", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ShowDownloadDialog(); } }); builder.setNegativeButton("Later", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); } private void ShowDownloadDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setCancelable(false); dialog.setTitle("Updating..."); LayoutInflater inflater = LayoutInflater.from(mContext); View v = inflater.inflate(R.layout.progress, null); mProgress = (ProgressBar) v.findViewById(R.id.progress); txtStatus = v.findViewById(R.id.txtStatus); dialog.setView(v); dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { intercept = true; } }); dialog.show(); DownloadApk(); } /** * 检查是否更新的内容 */ public void CheckUpdate() { new Thread(new Runnable() { @Override public void run() { String localVersion = "1"; try { localVersion = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName; //localVersion="20231024083955"; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } String versionName = "1"; String outputFile = ""; String config = doGet(checkUrl); if (config != null && config.length() > 0) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Matcher matcher = Pattern.compile("\"outputFile\":\\s*\"([^\"]*?)\"").matcher(config); if (matcher.find()) { outputFile = matcher.group(1); } matcher = Pattern.compile("\"versionName\":\\s*\"([^\"]*?)\"").matcher(config); if (matcher.find()) { String v = matcher.group(1); versionName = v.replace("v1.0.", ""); } } } if (Long.parseLong(localVersion) < Long.parseLong(versionName)) { apkUrl = apkUrl + outputFile; mHandler.sendEmptyMessage(SHOWDOWN); Log.e("部署版",versionName); Log.e("本班",localVersion); } else { return; } } }).start(); } /** * 从服务器下载APK安装包 */ public void DownloadApk() { downLoadThread = new Thread(DownApkWork); downLoadThread.start(); } private Runnable DownApkWork = new Runnable() { @Override public void run() { URL url; try { //如果下载地址是HTTPS,则把这段加上,http则不需要 SSLContext sslContext = SSLContext.getInstance("SSL");//第一个参数为 返回实现指定安全套接字协议的SSLContext对象。第二个为提供者 TrustManager[] tm = {new MyX509TrustManager()}; sslContext.init(null, tm, new SecureRandom()); SSLSocketFactory ssf = sslContext.getSocketFactory(); url = new URL(apkUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); int length = conn.getContentLength(); InputStream ins = conn.getInputStream(); FileOutputStream fos = new FileOutputStream(apkFile); int count = 0; byte[] buf = new byte[1024]; while (!intercept) { int numread = ins.read(buf); count += numread; progress = (int) (((float) count / length) * 100); // 下载进度 mHandler.sendEmptyMessage(DOWN_UPDATE); if (numread <= 0) { // 下载完成通知安装 mHandler.sendEmptyMessage(DOWN_OVER); break; } fos.write(buf, 0, numread); } fos.close(); ins.close(); } catch (Exception e) { e.printStackTrace(); } } }; //卸载 public void uninstallAPP() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_DELETE); intent.setData(Uri.parse("package:" + mContext.getApplicationContext().getPackageName())); mContext.startActivity(intent); installAPK(); } /** * 安装APK内容 */ public void installAPK() { try { if (!apkFile.exists()) { return; } Toast.makeText(mContext, "install", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//安装完成后打开新版本 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 给目标应用一个临时授权 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0 //如果SDK版本>=24,即:Build.VERSION.SDK_INT >= 24,使用FileProvider兼容安装apk String packageName = mContext.getApplicationContext().getPackageName(); String authority = new StringBuilder(packageName).append(".provider").toString(); Uri apkUri = FileProvider.getUriForFile(mContext, authority, apkFile); Log.e("packageName",packageName); Log.e("authority",authority); Log.e("apkFile", String.valueOf(apkFile)); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); } mContext.startActivity(intent); android.os.Process.killProcess(android.os.Process.myPid());//安装完之后会提示”完成” “打开”。 } catch (Exception e) { } } private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case SHOWDOWN: ShowUpdateDialog(); break; case DOWN_UPDATE: txtStatus.setText(progress + "%"); mProgress.setProgress(progress); break; case DOWN_OVER: Toast.makeText(mContext, "Download complete", Toast.LENGTH_SHORT).show(); uninstallAPP(); break; default: break; } } }; public static String doGet(String httpurl) { HttpURLConnection connection = null; InputStream is = null; BufferedReader br = null; String result = null; try { URL url = new URL(httpurl); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(15000); connection.setReadTimeout(60000); connection.connect(); if (connection.getResponseCode() == 200) { is = connection.getInputStream(); br = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer sbf = new StringBuffer(); String temp = null; while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); } result = sbf.toString(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } connection.disconnect(); } return result; } }