android 程序更新开发,android开发游记:APP自动更新功能的快速集成和实现方法讲解...

android的开发有时候让人很蛋疼,比如说app的更新,像ios的更新都被app store包办了方便快捷,但是国内的安卓市场却五花八门,途径各种各样。不要太期望像苹果那样把更新全权交个某夹或者某0,app内都要自己继承一个自动更新的功能。那我们就要自己实现一个。

效果图如下:

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

更新分成2种,一种是普通更新(如上图1)用户可以选择不更新,一种是强制更新(如上图2),新版本已经不再向下兼容,更新时会锁定屏幕,用户要么更新要么退出。

这里我把代码分享一下,更新功能都集成到了一个library中方便调用,下面先说下使用方法:

使用方法:

首先下载更新功能库library-version,导入工程后关联到自己项目:

library-version下载链接

然后在自己项目中需要检查更新的地方添加如下代码:

UpdateHelper updateHelper = new UpdateHelper.Builder(this)

.checkUrl(url)

.isAutoInstall(false) //设置为false需在下载完手动点击安装,默认值为true,下载后自动安装。

.build();

updateHelper.check();

如果你有复杂的需求,需要在更新过程中加入自己的处理逻辑,那么可以使用下面的接口:

UpdateHelper updateHelper = new UpdateHelper.Builder(this)

.checkUrl(url)

.isAutoInstall(false) //设置为false需在下载完手动点击安装,默认值为true,下载后自动安装。

.build();

updateHelper.check(new OnUpdateListener() {

@Override

public void onStartCheck() {

}

@Override

public void onFinishCheck(UpdateInfo info) {

}

@Override

public void onStartDownload() {

}

@Override

public void onInstallApk() {

}

@Override

public void onFinshDownload() {

}

@Override

public void onDownloading(int progress) {

}

});

有几点需要注意:

第一点:其中isAutoInstall(false)只适用于普通更新,强制更新一律自动安装。

第二点:其中url是你的apk的下载接口,你需要提供一个如下的接口:

{

"status":1,

"isForce":1,

"apkUrl":"http://dl.m.duoku.com/game/49000/49554/20150206145821_DuoKu.apk",

"versionCode":14,

"updateTips":"update1.1.7.2",

"versionName":"1.1.7.2",

"changeLog":"1.新增了用户信息的采集
2.修复了路径规划节点超过1000个异常崩溃的bug",

"size":"25M"}

参数说明:

参数名

类型

说明

是否必选

status

int

请求是否成功(1成功其他否)

isForce

int

是否强制更新(1是0否)

apkUrl

String

下载url

versionCode

int

版本号

updateTips

String

更新标题

versionName

String

版本名

changeLog

String

更新说明

size

String

包大小

其中版本号versionCode是判断是否需要更新的关键,它被设置在你的app的AndroidManifest.xml文件中:

package="com.ccrv.cber"

android:versionCode="13"

android:versionName="1.1.7.1" >

而版本名versionName只是用于给用户作展示用,它并不参与到逻辑中。这是android的版本管理规范。

提供了以上的接口功能集成就完成了,很方便吧。

下面解释下主要代码:不看实现原理的可以跳过了

先看下目录结构:

0818b9ca8b590ca3270a3433284dd417.png

解释下每个包中的类是用来干嘛的:

UpdateHelper:更新功能的主流程,程序的入口

VersionDialog:复用的几种的弹出对话

OnUpdateListener:更新过程的回调接口,如果有回调需要则需要自己实现

UpdateInfo:版本信息的实体类

com.shelwee.update.utils包下则都是些网络相关的工具类

library的主要处理流程都集中在UpdateHelper类中,在检查更新的时候首先调用了check方法:

public void check(OnUpdateListener listener) {

initButtonReceiver();

if (listener != null) {

this.updateListener = listener;

}

if (mContext == null) {

Log.e("NullPointerException", "The context must not be null.");

return;

}

AsyncCheck asyncCheck = new AsyncCheck();

asyncCheck.execute(checkUrl);

}

在check方法内部启动异步任务AsyncCheck去我们提供的接口获取服务器目前app信息,

通过JSONHandler类来获取返回信息并封装成UpdateInfo实体对象:

@Override

protected UpdateInfo doInBackground(String... params) {

...

updateInfo = JSONHandler.toUpdateInfo(HttpRequest.get(url));

...

return updateInfo;

}

在onPostExecute回调方法中,比较服务器最新版本和本地版本号,如果不是最新,则调用showUpdateUI(updateInfo)方法:

protected void onPostExecute(UpdateInfo updateInfo) {

if (mContext != null && updateInfo != null) {

if (Integer.parseInt(updateInfo.getVersionCode()) > getPackageInfo().versionCode) {

showUpdateUI(updateInfo);

...

} else {

Toast.makeText(mContext, "当前已是最新版", Toast.LENGTH_LONG).show();

...

}

}

}

在showUpdateUI方法中判断是否是强制更新来弹出不同的窗口和处理事件,并在点击事件中判断用户当前是否使用流量,如果是则调用showNetDialog(updateInfo)提示,如果不是则启动下载异步任务asyncDownLoad.execute(updateInfo):

/** * 弹出提示更新窗口 */

private void showUpdateUI(final UpdateInfo updateInfo) {

if (updateInfo.getIsForce()==0) {

//普通更新

final VersionDialog dialog = new VersionDialog(...,STYLE_UPDATE_NOMAL);

dialog.setOnPositiveListener(new OnClickListener() {

@Override

public void onClick(View v) {

dialog.dismiss();

NetWorkUtils netWorkUtils = new NetWorkUtils(mContext);

int type = netWorkUtils.getNetType();

if (type != 1) {

showNetDialog(updateInfo);

}else {

AsyncDownLoad asyncDownLoad = new AsyncDownLoad();

asyncDownLoad.execute(updateInfo);

}

}

});

dialog.show();

}else {

//强制更新

final VersionDialog dialog = new VersionDialog(...,STYLE_UPDATE_FORCE);

...

dialog.show();

}

}

下载任务中,每5%调用handler发送一次UPDATE_NOTIFICATION_PROGRESS消息来更新UI中的进度条;

并在下载完成的回调函数onPostExecute中给handler发送COMPLETE_DOWNLOAD_APK来通知安装:

@Override

protected Boolean doInBackground(UpdateInfo... params) {

...

FileOutputStream fos = new FileOutputStream(apkFile);

while ((length = inputStream.read(buf)) != -1) {

...

int progress = (int) ((count / (float) total) * 100);

if (progress % 5 == 0) {

handler.obtainMessage(UPDATE_NOTIFICATION_PROGRESS,progress, -1, params[0]).sendToTarget();

}

...

}

inputStream.close();

fos.close();

...

}

@Override

protected void onPostExecute(Boolean flag) {

...

handler.obtainMessage(COMPLETE_DOWNLOAD_APK).sendToTarget();

...

}

在handler的处理函数中,UPDATE_NOTIFICATION_PROGRESS消息调用showDownloadNotificationUI()来更新UI;

COMPLETE_DOWNLOAD_APK消息中判断是否自动安装来调用installApk()自动安装:

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case UPDATE_NOTIFICATION_PROGRESS:

showDownloadNotificationUI((UpdateInfo) msg.obj, msg.arg1);

break;

case COMPLETE_DOWNLOAD_APK:

if (UpdateHelper.this.isAutoInstall) {

...

//自动安装

installApk(Uri.parse("file://" + cache.get(APK_PATH)));

} else {

//点击通知栏消息进行手动安装

...

}

}

...

}

}

showDownloadNotificationUI判断是否是强制更新来决定是通知栏提示进度或者对话框提示进度:

private void showDownloadNotificationUI(UpdateInfo updateInfo,final int progress) {

if (mContext != null) {

if (updateInfo.getIsForce()==0) {

// 普通更新,通知栏提示

...

notificationManager.notify(DOWNLOAD_NOTIFICATION_ID,ntfBuilder.build());

}else {

// 强制更新,对话框提示

...

pd.show();

}

}

}

下面是安装apk的方法:

private void installApk(Uri data) {

...

Intent i = new Intent(Intent.ACTION_VIEW);

i.setDataAndType(data, "application/vnd.android.package-archive");

i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

mContext.startActivity(i);

...

}

以上插入的代码都省略过,为了方便讲解只贴出了重点代码行,具体代码请查看源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值