导入依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' // 必要依赖,解析json字符所用
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' // 必要依赖,和Rxjava结合必 须用到,下面会提到
implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依赖
implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依赖,切线程时需要用到
文件下载地址
public interface ApiMySerer {
String Url="https://alissl.ucdl.pp.uc.cn/fs08/2017/05/02/7/";
@Streaming
@GET("106_64d3e3f76babc7bce131650c1c21350d.apk")
Observable<ResponseBody> downloadimage();
}
xml布局的使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="match_parent"
tools:context="com.example.lenovo.kao02_zm0814_1.MainActivity">
<ImageView
android:id="@+id/id_main_img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher_round"/>
<TextView
android:id="@+id/id_main_dizhi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="下载地址"/>
<Button
android:id="@+id/id_main_button"
android:layout_gravity="center"
android:text="点击下载"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/id_main_progressbar"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:max="100"
android:progress="45"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/id_main_du"
android:text="下载进度45%"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
点击按钮,开始下载文件
@OnClick({R.id.id_main_img, R.id.id_main_button})
public void onClick(View v) {
switch (v.getId()) {
default:
break;
case R.id.id_main_img:
break;
case R.id.id_main_button:
mIdMainButton.setEnabled(false);
Intent intent = new Intent(this, MyService.class);
//启动服务
this.startService(intent);
break;
}
}
启动服务,开始下载文件
public class MyService extends Service {
private String TAG = "tag";
public MyService() {
}
//使用onStartCommand的方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
定义一个类,用来进行server和activiy之间的传值
public class DownloadInfo {
public String message;
public int progress;
public DownloadInfo(String message, int progress) {
this.message = message;
this.progress = progress;
}
public DownloadInfo() {
}
}
在onStartCommand的方法里面进行文件下载
public int onStartCommand(Intent intent, int flags, int startId) {
Retrofit build = new Retrofit.Builder()
.baseUrl(ApiMySerer.Url)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
build.create(ApiMySerer.class)
.downloadimage()
.subscribeOn(Schedulers.io())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(Disposable d) {
Log.i(TAG, "onSubscribe: 开始下载");
}
@Override
public void onNext(ResponseBody body) {
try {
//文件大小
long contentLength = body.contentLength();
//读取文件
InputStream inputStream = body.byteStream();
//创建一个文件夹
File directory = Environment.getExternalStorageDirectory();
File file = new File(directory, "0814-1.apk");
FileOutputStream outputStream = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len=0;
DownloadInfo downloadInfo = new DownloadInfo();
//循环读取文件的内容,把他放到新的文件目录里面
while ((len=inputStream.read(bytes))!= -1){
outputStream.write(bytes,0,len);
long length = file.length();
//获取下载的大小,并把它传给页面
int progress= (int) (length*100/contentLength);
downloadInfo.progress=progress;
Log.i(TAG, "onNext: =====>>"+progress);
EventBus.getDefault().post(downloadInfo);
}
//当下载完成后,利用粘性发送,并安装
EventBus.getDefault().postSticky(file);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError: e=="+e.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: 下载完成");
}
});
return super.onStartCommand(intent, flags, startId);
}
页面获取服务传过来的下载进度
@Subscribe(threadMode = ThreadMode.MAIN)
public void download(DownloadInfo info){
int progress = info.progress;
Log.i(TAG, "download: progress==="+progress);
String text="当前进度:"+progress+" %";
mIdMainDu.setText(text);
mIdMainProgressbar.setProgress(progress);
if (progress==100){
mIdMainButton.setEnabled(true);
//当文件下载完成后,跳转到安装页面进行安装
Intent intent = new Intent(this, AnActivity.class);
startActivity(intent);
}
}
安装页面进行获取数据进行安装
file = EventBus.getDefault().getStickyEvent(File.class);
download(file);
进行版本判断
public void download(File file){
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri=Uri.fromFile(file);
intent.setDataAndType(uri,"application/vnd.android.package-archive");
this.startActivityForResult(intent,2);
}else {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uriFile=FileProvider.getUriForFile(this,"",file);
intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(uriFile,"application/vnd.android.package-archive");
this.startActivityForResult(intent,2);
}
}
网友评论