在Android中APP自动更新、安装是必然的,最近呢我们公司也有这样一个需求开始呢本菜鸟是打算用AppUpdate但是呢看了他的项目后发现真的是个好东西但是我不打算这样做打算自己来实现更新、安装。无意之间在一个项目中发现了FileDownloader这个真是个好东西那么我立马下手果然…做出来了 而且还挺简单…
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.5'
implementation 'com.liulishuo.filedownloader:library:1.7.5'
RequestManager.getInstance().getApi.getAppMsg().compose(RxThreadUtlis.rxSchedulerHelper())
.subscribe(new RequestSubscribe() {
@Override
protected void onRequestScceed(RequestBaseBean response) {
if (response instanceof AppUpdateBean) {
AppUpdateBean appUpdateBean = (AppUpdateBean) response;
if (appUpdateBean != null) {
//比较APP版本和服务器版本是否一样
if (appUpdateBean.getData().get(0).getAppMsgId() != PackageUtlis.packageCode(AppApdateActivity.this)) {
new AlertDialog.Builder(AppApdateActivity.this)
.setTitle("应用更新")
.setMessage("检查到新版本啦,请安装更新~")
.setPositiveButton("立即更新", (dialog, which) -> {
dialog.dismiss();
downloadAPK();
}).setNeutralButton("稍后提醒", (dialog, which) -> dialog.dismiss()).create()
.show();
}
}
}
}
@Override
protected void onRequestErro(RequestBaseBean response) {
}
});
1、初始化FileDownloader
FileDownloader.setupOnApplicationOnCreate(this);
2、获取文件路径(如果文件存在则删除不存在则创建)
private String apkPath() {
String path = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file = new File(Environment.getExternalStorageDirectory().toString()+File.separator+"AppApdate");
if (file.exists() && file.isDirectory()){
for (File fileDir : file.listFiles()) {
if (fileDir.isFile()) {
fileDir.delete(); // 删除所有文件
}
}
}else {
file.mkdir();
}
path = file.getAbsolutePath();
}
return path;
}
3、使用FileDownloader下载
FileDownloader.getImpl().create(Constant.APK_URL).setPath(apkPath()+File.separator+"app.apk")
.setListener(new FileDownloadLargeFileListener() {
@Override
protected void pending(BaseDownloadTask task, long soFarBytes, long totalBytes) {
Log.e(DOWNLOAD_TAG,"pending");
}
@Override
protected void progress(BaseDownloadTask task, long soFarBytes, long totalBytes) {
Log.e(DOWNLOAD_TAG,"progress----"+(soFarBytes * 100 / totalBytes));
progressBar.setProgress((int) (soFarBytes * 100 / totalBytes));
tv_pg_d.setText("下载进度:"+(int) (soFarBytes * 100 / totalBytes)+"% / "+100+"%");
tv_pg_m.setText("已完成:"+soFarBytes/1024/1024+"MB / "+totalBytes/1024/1024+"MB");
}
@Override
protected void paused(BaseDownloadTask task, long soFarBytes, long totalBytes) {
Log.e(DOWNLOAD_TAG,"paused");
}
@Override
protected void completed(BaseDownloadTask task) {
Log.e(DOWNLOAD_TAG,"completed----------"+task.getPath());
progressBar.setProgress(100);
tv_pg_d.setText("下载进度:"+"100% / 100%");
installAPK(task.getPath());
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
Toast.makeText(AppApdateActivity.this,"下载错误",Toast.LENGTH_SHORT).show();
}
@Override
protected void warn(BaseDownloadTask task) {
Log.e(DOWNLOAD_TAG,"warn--:在下载队列中(正在等待/正在下载)已经存在相同下载连接与相同存储路径的任务");
}
}).start();
4、安装APK
/**
* 安装APK
* @param path
*/
private void installAPK(String path) {
File fileApk = new File(path);
if (!fileApk.exists()) {
Toast.makeText(IndexAc.this, "纯氧健身更新失败", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri apkUri = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
apkUri = FileProvider.getUriForFile(IndexAc.this, BuildConfig.APPLICATION_ID + ".provider", fileApk);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
apkUri = Uri.fromFile(fileApk);
}
intent.setDataAndType(apkUri,
"application/vnd.android.package-archive");
startActivity(intent);
}
5、配置:FileProvider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="files_root"
path="" />
</paths>
</resources>
path:需要临时授权访问的路径(.代表所有路径)
name:就是你给这个访问路径起个名字
添加权限(Android 6.0 后记得加上运行时权限哦~WRITE_EXTERNAL_STORAGE
6.0后需要动态申请)
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--安装权限-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
参考文章:
https://blog.csdn.net/qq_24852599/article/details/72539523
https://blog.csdn.net/cfy137000/article/details/70257912
参考项目连接:
https://github.com/sdwfqin/AppUpdate
FileDownloader地址:
https://github.com/lingochamp/FileDownloader
Github(我做了稍稍的修改不影响正常使用):
https://github.com/distantplace-z/BaseTools/blob/master/sample/src/main/java/com/xiaohou/sample/ui/download/DownloadActivity.java
这样更新就完成啦~
(注:此方法仅供参考个人尝试是成功了的)