前言
以前一直用的友盟更新,但是前段时间友盟更新不能用了,所以就自己封装了一个自动更新的方法,超级简单,一个方法就搞定,嘿嘿。。。
原理
首先往服务器存一个最新的apk,并将这个apk的versionCode存到数据库,然后每次进入app或者点击设置里面的版本更新时,向后台发请求获取当前最新版本的apk信息,将获取到的versionCode同当前app的versionCode进行比较,如果最新的versionCode大于当前版本的versionCode那么便说明我们先版本的app不是最新的,需要我们去更新,然后我们便去服务器下载这个apk,最后安装。
功能集成
你只要实现下面几步就可以完成自动更新代码了,自己直接拷贝代码就行了,当然自己如果有时间也可以完善下
服务器后台准备两个接口(向后台要)
- 获取当前版本信息的接口:versionCode必须有,其他根据具体需要来,比方说本次更新的信息
- 提供一个apk下载接口
在主界面调用更新方法(封装好的)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.....
new UpdateManager(mContext).checkUpdate(false);//就是这句,一行代码搞定
.....
}
- 点击设置里面的版本更新时调用方法
public void onClick(View view) {
switch (view.getId()) {
case R.id.setting_check_version:
new UpdateManager(mContext).checkUpdate(true);//还是这句,一行代码搞定
break;
}
}
代码实现
我这里下载只介绍了使用系统的下载功能,其他两种方法用的少,如果需要可以自行完善
- UpdataManager类
- checkUpdate(final boolean isToast)
- showNoticeDialog(String version_info)
public class UpdateManager {
private String TAG = "UpdateManager";
private Context mContext;
public UpdateManager(Context context) {
this.mContext = context;
}
/**
* 检测软件更新,这里主要是进行网络请求获取当前版本的信息,然后根据返回的versioncode判断是否跟新
* 这个方法的参数:isToast指的是否需要弹出“已经是最新版本”弹框,在首页肯定不需要弹出,设置里面需
* 要弹出,看上面功能集成的代码也能看出来
*/
public void checkUpdate(final boolean isToast) {
// 这里面就是单纯的网络请求,请换成自己的网络框架和URL就行
RequestParams params = new RequestParams();
// URLUtils.GET_UPDATE_INFO:获取当前版本信息的接口
NetUtils.doGet(URLUtils.GET_UPDATE_INFO, params, new TextHttpResponseHandler() {
@Override
public void onFailure(“网络请求失败了”) {
LogUtils.e(TAG, "获取系统版本号失败" + responseString);
}
@Override
public void onSuccess(“网络请求成功了”) {
LogUtils.e(TAG, "获取系统版本号成功" + responseString);
int mVersion_code = DeviceUtil.getVersionCode(mContext);// 当前的版本号
int nVersion_code = JsonParseUtil.getInt(responseString,"code",0);// 最新的版本号
String version_info = JsonParseUtil.getString(responseString,"description");
if(mVersion_code < nVersion_code){// 需要更新
showNoticeDialog(version_info);// 显示更新提示对话框
}else{// 已经是最新的版本
if(isToast){
ToastUtil.show(mContext, "已经是最新版本");
}
}
}
});
}
/**
* 显示软件更新对话框
*/
public void showNoticeDialog(String version_info) {
// 构造对话框
Builder builder = new Builder(mContext);
builder.setTitle(R.string.soft_update_title);
builder.setMessage(version_info);
// 更新
builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
ToastUtil.show(mContext, "程序正在后台下载,可在通知栏查看下载进度");
// 首先注册一个广播接收者,用于在下载完成后安装apk
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.DOWNLOAD_COMPLETE");
filter.addAction("android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED");
BroadcastReceiver receiver = new CompleteReceiver();
mContext.registerReceiver(receiver, filter);
// 调用系统的下载功能去下载应用
DownloadManager downloadManager = (DownloadManager)
mContext.getSystemService(mContext.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(URLUtils.DOWN_APK);// URLUtils.DOWN_APK:apk下载的接口
Request request = new Request(uri);
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
request.setVisibleInDownloadsUi(false);
request.setTitle("手机QQ更新");
// 这个id要保存起来,在广播接收者里面会根据它判断是否成功下载
long id = downloadManager.enqueue(request);
ShareUtils.putString(ShareUtils.UPDATE_ID, String.valueOf(id));
}
});
// 稍后更新
builder.setNegativeButton(R.string.soft_update_later, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
Dialog noticeDialog = builder.create();
noticeDialog.show();
}
}
=====================================================================================
- CompleteReceiver:广播接收者
public class CompleteReceiver extends BroadcastReceiver
{
// 接收到下载完成的广播后,检查是否是一个apk,然后安装
@Override
public void onReceive(Context arg0, Intent intent)
{
DownloadManager manager = (DownloadManager) arg0.getSystemService(Context.DOWNLOAD_SERVICE);
long did = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
//获取调用DownloadManager时保存的id
long myid = Long.parseLong(ShareUtils.getString(ShareUtils.UPDATE_ID,""));
if(myid!=did){// 用于验证是否是下载的同一个apk
return;
}
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(did);
Cursor c = manager.query(query);
if (c.moveToFirst())
{
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status)
{
case DownloadManager.STATUS_SUCCESSFUL:
//如果文件名不为空,说明已经存在了,然后获取uri,进行安装
File path = new File(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)));
if(!path.exists()){
return;
}
Uri uri = Uri.fromFile(path);
Intent install = new Intent(Intent.ACTION_VIEW);
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.setDataAndType(uri,"application/vnd.android.package-archive");
// 执行意图进行安装
arg0.startActivity(install);
break;
default:
manager.remove(did);
break;
}
}
}
}
总结
这样一个简单的自动更新功能就这样完成了,怎么样,是不是感觉很简单啊,第一次认真的写一个博客,希望大家多多指教,本人小白,轻虐。。。
后话
这个正如评论里面的哥们说的一样,有一些机型确实不支持DownloadManager这个方法,所以我针对这个情况将下载部分和通知部分使用Retrofit + OkHttp + RxBus + Notification + Service分别实现了后台的下载以及前台的通知展示,大家可以参考一下高逼格,超简单,实现App自动更新,一个方法搞定希望大家可以多多提建议,我会及时改进的,谢谢大家的支持。