创建HandlerThread
mWorkThread = new HandlerThread("download");
mWorkThread.start();
mHandler = new Handler(mWorkThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:// 开始下载
String url = msg.obj.toString();
downloadAPK(url, AppInfo.getVersionName(mContext.get()));
break;
case 2:
checkDownloadStatus();//检查下载状态
break;
case 3:
//下载完成安装APK
String downloadPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
+ File.separator + AppInfo.getVersionName(mContext.get());
installAPK(new File(downloadPath));
mUpdateVersionDialog.dismiss();
break;
}
}
};
下载
name 参数是你下载文件后文件的名字,安装时候要根据这个名字找到这个文件
private void downloadAPK(String versionUrl, String name) {
//创建下载任务
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(versionUrl));
request.setAllowedOverRoaming(true);//漫游网络是否可以下载
//设置文件类型,可以在下载结束后自动打开该文件
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(versionUrl));
request.setMimeType(mimeString);
//在通知栏中显示,默认就是显示的
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setVisibleInDownloadsUi(true);
//sdcard的目录下的download文件夹
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,name);
// request.setDestinationInExternalFilesDir(,"",getApkPath()),
//将下载请求加入下载队列
mDownloadManager = (DownloadManager) mContext.get().getSystemService(Context.DOWNLOAD_SERVICE);
//加入下载队列后会给该任务返回id
mTaskId = mDownloadManager.enqueue(request);
mHandler.sendEmptyMessage(2);
}
检查下载状态
//检查下载状态
private void checkDownloadStatus() {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(mTaskId);//筛选下载任务,传入任务ID,可变参数
Cursor c = mDownloadManager.query(query);
if (c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
case DownloadManager.STATUS_PAUSED:
Log.i("tag", ">>>下载暂停");
case DownloadManager.STATUS_PENDING:
Log.i("tag", ">>>下载延迟");
case DownloadManager.STATUS_RUNNING:
Log.e("tag", ">>>正在下载");
setProgress(c);
break;
case DownloadManager.STATUS_SUCCESSFUL:
Log.e("tag", ">>>下载完成");
mHandler.sendEmptyMessage(3);
break;
case DownloadManager.STATUS_FAILED:
Log.i("tag", ">>>下载失败");
break;
}
}
}
显示下载进度
private void setProgress(Cursor c) {
//已经下载的字节数
int bytes_downloaded = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
//总需下载的字节数
int bytes_total = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (bytes_downloaded != 0) {
double progress = div(bytes_downloaded, bytes_total, 2);
Log.e("tag", "checkDownloadStatus: " + bytes_downloaded + "-" + bytes_total + "-" + progress + "-" + (int) (progress * 100));
mContext.get().runOnUiThread(() -> mUpdateVersionDialog.setProgress((int) (progress * 100)));
}
mHandler.sendEmptyMessageDelayed(2, 1000);
}
带小数点后两位的除法
public static double div(double v1, double v2, int scale) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
下载后安装
//下载到本地后执行安装
protected void installAPK() {
String downloadPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
+ File.separator + AppInfo.getVersionName(mContext.get());
File file = new File(downloadPath);
if (!file.exists()) return;
//参数2配置文件中一致 参数3 download文件夹位置
Uri apkUri = FileProvider.getUriForFile(mContext.get(), "xxx", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
mContext.get().startActivity(intent);
}
file_paths.xml :用FileProvider需要建一个xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="download"/>
</paths>
</resources>
并在清单文件中加provider
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="xxx"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
补充:权限
<!--安装应用权限-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INTERNET" />