本文章demo下载地址:app升级Demo
效果图:
基本上开发了app后都会有升级,很多app都是放在应用商店,然后由应用商店升级,那么如果不想走app应用商店,想通过自己的服务器升级该怎么办呢?
网上很多都是用Android自带的DownLoadManager类来下载,使用该类的一般升级步骤如下:
- 通过getSystemService来获取DownLoadManager类。
manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
- 初始化DownLoadManager类的Request。
String urlPath = "http://116.196.89.193/app-realse.apk";
Uri parse = Uri.parse(urlPath);
DownloadManager.Request down = new DownloadManager.Request(parse);
- 设置下载的apk保存地址,并调用DownLoadManager的enqueue方法请求异步下载。
down.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, apkName);
// 将下载请求放入队列
manager.enqueue(down);
- 注册一个广播来接收下载完成的通知,完成的事件为DownloadManager.ACTION_DOWNLOAD_COMPLETE
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
- 安装apk
关于DownloadManager更新app,网上资料很多,这里就不作详细述说了。
本文推荐的升级方案是用文件的形式将apk下载下来,然后再通过apk文件安装,下载apk可以用retrofit2来实现,不过retrofit2有大小限制,比较麻烦。这里推荐一个第三方下载文件的库*filedownloader。gradle依赖路径为:*
compile 'com.liulishuo.filedownloader:library:1.6.8'
添加依赖后,接下来就是使用该库来升级app了,这里分为四步:
1.添加网络及文件读写权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2.初始化filedownloader
在工程的application类中或者下载的Activity中初始化该类。
FileDownloader.setup(getApplicationContext());
3.封装一个下载方法
/** 下载apk文件
* @param url 下载地址
*/
private void downloadApk(String url){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("程序升级中……");
progressDialog.setCanceledOnTouchOutside(false);
FileDownloader.getImpl().create(url)
.setPath(DOWN_LOAD_APK_PATH) // DOWN_LOAD_APK_PATH为apk下载完成后放置的路径
.setListener(new FileDownloadListener() {
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
showLog("pending");
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.show();
}
});
}
@Override
protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
showLog("connected");
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
showLog("progress "+soFarBytes+" total is "+totalBytes);
final StringBuilder builder = new StringBuilder();
builder.append("程序升级中……")
.append(soFarBytes/1024)
.append("KB/")
.append(totalBytes/1024)
.append("KB");
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setMessage(builder.toString());
}
});
}
@Override
protected void blockComplete(BaseDownloadTask task) {
}
@Override
protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
}
@Override
protected void completed(BaseDownloadTask task) {
showLog("down completed");
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
}
});
installApk();
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
}
});
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
showLog("error "+e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
Toast.makeText(MainActivity.this,
"升级失败,请稍后再试",Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void warn(BaseDownloadTask task) {
}
}).start();
}
4.下载完成后安装
/**
* 安装apk
*/
void installApk() {
Intent intent = new Intent(Intent.ACTION_VIEW);
File apkFile = new File(DOWN_LOAD_APK_PATH);
intent.setDataAndType(Uri.fromFile(apkFile),
"application/vnd.android.package-archive");
startActivity(intent);
}