安装的时候我是用的第三方库来实现的:
//工具库
implementation 'com.blankj:utilcode:1.25.9'
权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- 8.0手机安装软件 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
获取当前版本号的工具类:
public class APKVersionCodeUtils {
/**
*获取本地版本号
*
*/
public static int getVersionCode(Context mContext) {
int versionCode = 0;
try {
//获取软件版本号,对应AndroidManifest.xml下android:versionCode
versionCode = mContext.getPackageManager().
getPackageInfo(mContext.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionCode;
}
/**
* 获取版本号名称
*
* @param context 上下文
* @return
*/
public static String getVerName(Context context) {
String verName = "";
try {
verName = context.getPackageManager().
getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return verName;
}
}
进入正题
首先我们要判断一下当前版本号和接口传过来的版本号:
if (APKVersionCodeUtils.getVersionCode(this) < hintBean.getCode()){
loadNewVersionAlertDiaLog();
}else {
//Toast.makeText(this, "最新版本", Toast.LENGTH_SHORT).show();
}
如果当前版本小于接口的版本号就提示用户升级并下载安装:
(下面整体复制粘贴即可)
public void loadNewVersionAlertDiaLog() {
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("说明");
alert.setMessage("发现新版本,是否立即更新?");
alert.setPositiveButton("更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
downloadApk();
}
});
alert.setNegativeButton("暂不更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
alert.create();
alert.show();
}
/**
* 从服务器端下载最新apk
*/
private void downloadApk() {
//显示下载进度
ProgressDialog dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.show();
new Thread(new DownloadApk(dialog)).start();
}
/**
* 访问网络下载apk
*/
private class DownloadApk implements Runnable {
private ProgressDialog dialog;
InputStream is;
FileOutputStream fos;
private String TAG;
public DownloadApk(ProgressDialog dialog) {
this.dialog = dialog;
}
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
//String url = "http://teacher-asked.oss-cn-hangzhou.aliyuncs.com/versions/1/2/app-debug.apk"; //下载路径
//直接获取接口里的Url就是活数据啦
Request request = new Request.Builder().get().url(url).build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
Log.d(TAG, "开始下载apk");
//获取内容总长度
long contentLength = response.body().contentLength();
//设置最大值
dialog.setMax((int) contentLength);
//保存到sd卡
File apkFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".apk");
fos = new FileOutputStream(apkFile);
//获得输入流
is = response.body().byteStream();
//定义缓冲区大小
byte[] bys = new byte[1024];
int progress = 0;
int len = -1;
while ((len = is.read(bys)) != -1) {
try {
Thread.sleep(1);
fos.write(bys, 0, len);
fos.flush();
progress += len;
//设置进度
dialog.setProgress(progress);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//下载完成,提示用户安装 (第三方库)
AppUtils.installApp(apkFile);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭io流
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
is = null;
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
fos = null;
}
}
dialog.dismiss();
}
}
如果你想自定义进度条样式 那就用到了ProgressBar了
自定义ProgressBar样式,在 res/drawable 下创建 progress_indeterminate_horizontal.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--未加载的进度区域-->
<item android:id="@android:id/background">
<shape>
<!--进度条的圆角-->
<corners android:radius="15dip" />
<!--未加载的进度区域颜色-->
<solid android:color="#FFDBDBDB"/>
</shape>
</item>
<!--缓冲的进度的颜色,一般视频播放的缓冲区域-->
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<!--进度条的圆角-->
<corners android:radius="15dip" />
<!--缓冲的进度的颜色,一般视频播放的缓冲进度-->
<solid android:color="#80C07AB8"/>
</shape>
</clip>
</item>
<!--已经加载完的进度的区域-->
<item android:id="@android:id/progress">
<clip>
<shape>
<!--进度条的圆角-->
<corners android:radius="15dip" />
<!--已经加载完的进度的颜色-->
<solid android:color="#FF706EB3"/>
</shape>
</clip>
</item>
</layer-list>
res/values/styles.xml:
<style name="update_progress_horizontal" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<!--进度条的进度颜色drawable文件-->
<item name="android:progressDrawable">@drawable/progress_indeterminate_horizontal</item>
<!--进度条的最小高度-->
<item name="android:minHeight">10dp</item>
<!--进度条的最大高度-->
<item name="android:maxHeight">10dp</item>
</style>
progressbar.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">
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/update_progress_horizontal"
android:layout_margin="@dimen/dp_10"
/>
</LinearLayout>
private ProgressBar bar;
/**
* 从服务器端下载最新apk
*/
private void downloadApk() {
//显示下载进度
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setCancelable(false);
alertDialog.show();
Window window = alertDialog.getWindow();
alertDialog.setContentView(R.layout.progressbar);
bar = window.findViewById(R.id.progress);
new Thread(new DownloadApk(alertDialog)).start();
}
//访问网络下载apk
private class DownloadApk implements Runnable {
private AlertDialog dialog;
InputStream is;
FileOutputStream fos;
private String TAG;
public DownloadApk(AlertDialog dialog) {
this.dialog = dialog;
}
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().get().url(url).build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
Log.d(TAG, "开始下载apk");
//获取内容总长度
long contentLength = response.body().contentLength();
//设置最大值
bar.setMax((int) contentLength);
//保存到sd卡
File apkFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".apk");
fos = new FileOutputStream(apkFile);
//获得输入流
is = response.body().byteStream();
//定义缓冲区大小
byte[] bys = new byte[1024];
int progress = 0;
int len = -1;
while ((len = is.read(bys)) != -1) {
try {
Thread.sleep(1);
fos.write(bys, 0, len);
fos.flush();
progress += len;
//设置进度
bar.setProgress(progress);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//下载完成,提示用户安装 (第三方库)
AppUtils.installApp(apkFile);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭io流
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
is = null;
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
fos = null;
}
}
dialog.dismiss();
}
}