vironment.getExternalStorageDirectory() + "/Download/" + s1;
EventBus.getDefault().post(SUCCESS);
}
事件监听
创建一个方法,方法名自定义,参数类型为你通过EventBus发送的类型,用于获取进度和改变通知的进度条百分比
// 创建EventBus监听
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void UpdateEventBus(Integer message) {
// 转换百分比,不先除再乘的原因是int小于1会转换0
int a = currentSize * 100;
int b = a / maxSize;
// 设置notification的内容,每次通过EventBus监听到数据时都去改变百分比
build.setContentText("下载中:" + b + "%");
// 设置进度条,进度条无需改变参数
build.setProgress(maxSize, currentSize, false);
// 发送通知
nManager.notify(1, build.build());
// 当文件下载完成后
if (message == SUCCESS) {
Intent install = StartInstall();
PendingIntent intent = PendingIntent.getActivity(this, 0, install, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CHANNEL_ID")
.setSmallIcon(R.drawable.ic_baseline_arrow_drop_down_circle_24)
.setContentTitle("下载完成")
.setContentText("点击安装")
.setContentIntent(intent);
nManager.cancel(1);
nManager.notify(2, builder.build());
}
if (message == FAILED) {
Toast.makeText(this, "软件更新失败", Toast.LENGTH_SHORT).show();
}
}
字节转换
在文件下载的写入环节有一个currentSize = transitionBit(progress);这个方法是将单位为b的转换成mb,用于获取人们普遍认知的文件大小
// b转mb
private Integer transitionBit(long b) {
long l = b / 1024;
long l1 = l / 1024;
return Math.toIntExact(l1);
}
单位的转换基本规则如下:
1B(字节)=8b(位)
1 KB = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
1TB = 1024GB
所以b转成mb只需要乘上两个1024即可
字符串反转
在文件下载设置文件安装包名称的时候我遇到了一个难题,微信的下载链接中安装包名即不在最后又不在最前,所以我通过反转后进行字符的截取操作,然后再反转一便就是安装包的名称了
// 字符串反转
private String StringReverse(String str) {
StringBuffer stringBuffer = new StringBuffer(str);
String s = stringBuffer.reverse().toString();
return s;
}
安装程序
当我们完成了文件的下载后,再事件监听中会销毁进度条的通知创建一个下载完成安装通知,我们通过通知的setContentIntent(intent);设置安装程序,安装程序我们封装成一个方法
// 安装程序
public Intent StartInstall() {
Intent install = new Intent(Intent.ACTION_VIEW);
// 设置FLAG_ACTIVITY_NEW_TASK,确保软件安装后返回该页面
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 临时访问读权限 设置FLAG_GRANT_READ_URI_PERMISSION,intent的接受者将被授予 INTENT数据uri或者在ClipData上的读权限。
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 安卓官方更推荐使用 FileProvider.getUriForFile来获取文件的uri
// 要使用FileProvider需要在AndroidManifest文件中申明,authority参数需要与AndroidManifest文件声明的provider标签一致
Uri uri = FileProvider.getUriForFile(this, "com.example.android_study.fileprovider", new File(filepath));
install.setDataAndType(uri, "application/vnd.android.package-archive");
// 将设置好的intent返回
return install;
}
install.setDataAndType中传入的第二个参数是安装apk所必需的,具体文件类型对比表如下
// install取设置属于和类型,数据就是获取到的uri,更具文件类型不同,type参数也不相同,具体参考下表
/*{后缀名,MIME类型}
{".3gp", "video/3gpp"},
{".apk", "application/vnd.android.package-archive"},
{".asf", "video/x-ms-asf"},
{".avi", "video/x-msvideo"},
{".bin", "application/octet-stream"},
{".bmp", "image/bmp"},
{".c", "text/plain"},
{".class", "application/octet-stream"},
{".conf", "text/plain"},
{".cpp", "text/plain"},
{".doc&q