Android 简单直白的版本更新下载APP自动安装(带进度条)
程序员文章站
2022-04-12 22:41:52
一个项目的基础功能几乎都要配备这个需求,版本更新,我们根据判断当前的APK版本信息和服务器校验,是否下载,今天我们只聊一下下载自动更新的功能实现第一步.下载工具类(包含进度框+自动安装)//负责软件更新模块public class UpdateUnit { private Context context; private String url; // 更新提示语 // private String upDateMSG = "有更新,是否现在更新?"; //...
一个项目的基础功能几乎都要配备这个需求,版本更新,我们根据判断当前的APK版本信息和服务器校验,是否下载,今天我们只聊一下下载自动更新的功能实现
第一步.下载工具类(包含进度框+自动安装)
//负责软件更新模块 public class UpdateUnit { private Context context; private String url; // 更新提示语 // private String upDateMSG = "有更新,是否现在更新?"; // 获取SD卡根目录 private static final String ROOT = Environment.getExternalStorageDirectory().getPath(); // 文件保存路径 private static final String savePath = ROOT + "/MyAPP/"; // 文件路径+文件名 private static final String saveFilePath = savePath + "MyAPP.apk"; // 进度条 private ProgressBar progressBar; private TextView tv_bfb; private int progress; private Button bt_down; // 下载标识 private static final int DOWN_UPDATE = 0; // 结束下载标识 private static final int DOWN_OVER = 1; // 下载错误标识 private static final int DOWN_FAIL = 2; // 取消下载按钮标识 private boolean interceptFlag = false; // 子线程 private Thread downloadThread; public UpdateUnit(Context context, String url) { this.context = context; this.url = url; } // 外部接口 让Activity调用 public void updateInfo() { showdownDialog(); } // 显示提示对话框 //private void shownoticeDialog() { /*AlertDialog.Builder SNDialog = new AlertDialog.Builder(context);
SNDialog.setTitle("软件版本更新");
SNDialog.setMessage(upDateMSG);
// 确定更新按钮
SNDialog.setPositiveButton("立即更新", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
// 调用下载对话框
showdownloadDialog();
}
});
// 以后再说按钮
SNDialog.setNeutralButton("以后再说", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
// 设置对话框失去焦点的时候仍然不消失
SNDialog.setCancelable(false);
SNDialog.create();
SNDialog.show();*/ //} // 显示下载对话框 private void showdownDialog() { Builder SDDialog = new Builder(context); // 显示进度条 LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.dialog_pgsbar, null); progressBar = view.findViewById(R.id.progressBar); tv_bfb=view.findViewById(R.id.tv_bfb); bt_down=view.findViewById(R.id.bt_down); // Button bt_pgsbar=view.findViewById(R.id.bt_pgsbar); SDDialog.setView(view); bt_down.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); /*bt_pgsbar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
interceptFlag = true;
}
});*/ // 取消按钮 SDDialog.setNeutralButton("Cancel", (dialog, which) -> { dialog.dismiss(); interceptFlag = true; }); // 设置对话框失去焦点的时候仍然不消失 SDDialog.setCancelable(false); SDDialog.create(); SDDialog.show(); downloadAPK(); } // 下载APK private void downloadAPK() { downloadThread = new Thread(downAPKRunnable); downloadThread.start(); } // 子线程中执行下载 private Runnable downAPKRunnable = new Runnable() { @Override public void run() { try { URL uri = new URL(Api.HOST + url); HttpURLConnection urlConnection = (HttpURLConnection) uri .openConnection(); urlConnection.connect(); // 获取下载文件长度 int apkLength = urlConnection.getContentLength(); InputStream inputStream = urlConnection.getInputStream(); // 创建文件保存路径 File file = new File(savePath); if (!file.exists()) { file.mkdir(); } File APKFile = new File(saveFilePath); FileOutputStream fileOutputStream = new FileOutputStream( APKFile); // 已经下载的长度 int count = 0; byte[] bs = new byte[1024]; do { int num = inputStream.read(bs); count += num; progress = (int) (((float) count / apkLength) * 100); handler.sendEmptyMessage(DOWN_UPDATE); if (num <= 0) { handler.sendEmptyMessage(DOWN_OVER); break; } fileOutputStream.write(bs, 0, num); } // 点击取消停止下载 while (!interceptFlag); fileOutputStream.close(); inputStream.close(); } catch (Exception e) { handler.sendEmptyMessage(DOWN_FAIL); e.printStackTrace(); } } }; // 使用Handler更新进度 private Handler handler = new Handler() { @SuppressLint("HandlerLeak") public void handleMessage(@NotNull Message msg) { switch (msg.what) { // 正在下载,更新进度 case DOWN_UPDATE: tv_bfb.setText(progress+"%"); progressBar.setProgress(progress); break; // 下载结束 case DOWN_OVER: installAPK(); break; case DOWN_FAIL: Toast.makeText(context, "文件下载失败!", Toast.LENGTH_LONG).show(); break; } } }; // 安装APK private void installAPK() { File apkFile = new File(saveFilePath); if (!apkFile.exists()) { return; } Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive"); context.startActivity(i); } }
第二步.进度条xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="@string/downloading" android:textColor="@color/blue" android:textSize="16sp" android:textStyle="bold" android:layout_marginTop="10dp"/> <ProgressBar
android:id="@+id/progressBar" android:layout_marginTop="20dp" android:layout_centerHorizontal="true" android:layout_width="match_parent" android:layout_marginRight="20dp" android:layout_marginLeft="20dp" android:layout_gravity="center" android:layout_height="10dp" android:max="100" android:progress="0" android:progressDrawable="@drawable/progress_white" style="@android:style/Widget.ProgressBar.Horizontal" /> <TextView
android:id="@+id/tv_bfb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textColor="@color/white" android:textSize="12sp" android:layout_marginTop="10dp"/> <Button
android:id="@+id/bt_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textColor="@color/white" android:background="@drawable/shape_bt_regist" android:textSize="12sp" android:text="@string/cancel" android:visibility="gone" android:layout_marginTop="10dp"/> </LinearLayout>
第三步 直接调用即可
UpdateUnit(this, "下载路径").updateInfo()
这个是我之前封装的简单粗暴的版本更新,有需要完善的地方 还需要小伙伴多多指点。
本文地址:https://blog.csdn.net/qq_28643195/article/details/107787947