1,参数 appkey app的唯一标志
appkey可以在manifest文件中配置,也可以在代码中添加
xml配置如下:
<meta-dataandroid:name="UPDATE_APP_KEY"android:value="ab55ce55Ac4bcP408cPb8c1Aaeac179c5f6f"/>
2,参数 version 版本号,工具自动添加(服务器判断客户端传过来的version和服务器存的最新的version,决定是否更新)
3, 服务器app后台管理界面 1,有新版本
{
"update": "Yes",//有新版本"new_version": "0.8.3",//新版本号"apk_file_url": "https://raw.githubusercontent.com/WVector/AppUpdateDemo/master/apk/app-debug.apk", //apk下载地址"update_log": "1,添加删除信用卡接口\r\n2,添加vip认证\r\n3,区分自定义消费,一个小时不限制。\r\n4,添加放弃任务接口,小时内不生成。\r\n5,消费任务手动生成。",//更新内容"target_size": "5M",//apk大小"new_md5":"A818AD325EACC199BC62C552A32C35F2",
"constraint": false//是否强制更新
}
2,没有新版本
{
"update": "No",//没有新版本
}
和自定义相比,不需要传自定义参数,和实现parseJson方法,其他都一样。
//最简方式newUpdateAppManager
.Builder()
//当前Activity
.setActivity(this)
//更新地址
.setUpdateUrl(mUpdateUrl)
//实现httpManager接口的对象
.setHttpManager(newUpdateAppHttpUtil())
.build()
.update();
根据自己项目的接口,自己传参数给服务器,实现parseJson方法,解析json,设置新版本app信息。
同时可以设置以下功能
- 请求方式,get,post
- 请求参数
- 是否显示下载进度对话框
- 对话框顶部图片(设置图片后自动识别主色调,然后为按钮,进度条设置颜色)
- 按钮,进度条颜色
- apk的下载路径
- 是否忽略版本
- 是否显示通知栏进度条
如果以下的例子出错,请看项目中详细的使用案例
Stringpath = Environment.getExternalStorageDirectory().getAbsolutePath();
Map<String, String> params = newHashMap<String, String>();
params.put("appKey", "ab55ce55Ac4bcP408cPb8c1Aaeac179c5f6f");
params.put("appVersion", Utils.getVersionName(this));
params.put("key1", "value2");
params.put("key2", "value3");
newUpdateAppManager
.Builder()
//必须设置,当前Activity
.setActivity(this)
//必须设置,实现httpManager接口的对象
.setHttpManager(newOkGoUpdateHttpUtil())
//必须设置,更新地址
.setUpdateUrl(mUpdateUrl)
//以下设置,都是可选//设置请求方式,默认get
.setPost(false)
//添加自定义参数,默认version=1.0.0(app的versionName);apkKey=唯一表示(在AndroidManifest.xml配置)
.setParams(params)
//设置点击升级后,消失对话框,默认点击升级后,对话框显示下载进度
.hideDialogOnDownloading(false)
//设置头部,不设置显示默认的图片,设置图片后自动识别主色调,然后为按钮,进度条设置颜色
.setTopPic(R.mipmap.top_8)
//为按钮,进度条设置颜色,默认从顶部图片自动识别。//.setThemeColor(ColorUtil.getRandomColor())//设置apk下砸路径,默认是在下载到sd卡下/Download/1.0.0/test.apk
.setTargetPath(path)
//设置appKey,默认从AndroidManifest.xml获取,如果,使用自定义参数,则此项无效//.setAppKey("ab55ce55Ac4bcP408cPb8c1Aaeac179c5f6f")//不显示通知栏进度条
.dismissNotificationProgress()
//是否忽略版本//.showIgnoreVersion()
.build()
//检测是否有新版本
.checkNewApp(newUpdateCallback() {
/** * 解析json,自定义协议 * * @param json 服务器返回的json * @return UpdateAppBean */@OverrideprotectedUpdateAppBeanparseJson(Stringjson) {
UpdateAppBeanupdateAppBean = newUpdateAppBean();
try {
JSONObjectjsonObject = newJSONObject(json);
updateAppBean//(必须)是否更新Yes,No
.setUpdate(jsonObject.optString("update"))
//(必须)新版本号,
.setNewVersion(jsonObject.optString("new_version"))
//(必须)下载地址
.setApkFileUrl(jsonObject.optString("apk_file_url"))
//(必须)更新内容
.setUpdateLog(jsonObject.optString("update_log"))
//大小,不设置不显示大小,可以不设置
.setTargetSize(jsonObject.optString("target_size"))
//是否强制更新,可以不设置
.setConstraint(false)
//设置md5,可以不设置
.setNewMd5(jsonObject.optString("new_md51"));
} catch (JSONExceptione) {
e.printStackTrace();
}
returnupdateAppBean;
}
/** * 网络请求之前 */@OverridepublicvoidonBefore() {
CProgressDialogUtils.showProgressDialog(JavaActivity.this);
}
/** * 网路请求之后 */@OverridepublicvoidonAfter() {
CProgressDialogUtils.cancelProgressDialog(JavaActivity.this);
}
/** * 没有新版本 */@OverridepublicvoidnoNewApp() {
Toast.makeText(JavaActivity.this, "没有新版本", Toast.LENGTH_SHORT).show();
}
});
其他代码和上面一样,只需重写UpdateCallback 的 hasNewApp方法,然后调用自己的对话框
/** * 有新版本 * * @param updateApp 新版本信息 * @param updateAppManager app更新管理器 */@OverridepublicvoidhasNewApp(UpdateAppBeanupdateApp, UpdateAppManagerupdateAppManager) {
//自定义对话框showDiyDialog(updateApp, updateAppManager);
}下面是简单的对话框,新版本信息从 updateApp 对象获取,updateAppManager 可以控制后台开始下载,下载完自动安装
直接调用 'updateAppManager.download();' ,进行下载。
/** * 自定义对话框 * * @param updateApp * @param updateAppManager */privatevoidshowDiyDialog(finalUpdateAppBeanupdateApp, finalUpdateAppManagerupdateAppManager) {
StringtargetSize = updateApp.getTargetSize();
StringupdateLog = updateApp.getUpdateLog();
Stringmsg = "";
if (!TextUtils.isEmpty(targetSize)) {
msg = "新版本大小:" + targetSize + "\n\n";
}
if (!TextUtils.isEmpty(updateLog)) {
msg += updateLog;
}
newAlertDialog.Builder(this)
.setTitle(String.format("是否升级到%s版本?", updateApp.getNewVersion()))
.setMessage(msg)
.setPositiveButton("升级", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterfacedialog, intwhich) {
//不显示下载进度updateAppManager.download();
dialog.dismiss();
}
})
.setNegativeButton("暂不升级", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterfacedialog, intwhich) {
dialog.dismiss();
}
})
.create()
.show();
}和上面的例子只有在控制下载有区别,传个回调,监听到下载进度。
onFinish() 当返回 true :下载完自动跳到安装界面,false:则不进行安装
updateAppManager.download(newDownloadService.DownloadCallback() {
@OverridepublicvoidonStart() {
HProgressDialogUtils.showHorizontalProgressDialog(JavaActivity.this, "下载进度", false);
}
/** * 进度 * * @param progress 进度 0.00 -1.00 ,总大小 * @param totalSize 总大小 单位B */@OverridepublicvoidonProgress(floatprogress, longtotalSize) {
HProgressDialogUtils.setProgress(Math.round(progress * 100));
}
/** * * @param total 总大小 单位B */@OverridepublicvoidsetMax(longtotal) {
}
/** * 下载完了 * @param file 下载的app * @return true :下载完自动跳到安装界面,false:则不进行安装 */@OverridepublicbooleanonFinish(Filefile) {
HProgressDialogUtils.cancel();
returntrue;
}
@OverridepublicvoidonError(Stringmsg) {
Toast.makeText(JavaActivity.this, msg, Toast.LENGTH_SHORT).show();
HProgressDialogUtils.cancel();
}
});以下是使用默认协议的例子,
/** * 静默下载,下载完才弹出升级界面 * * @param view */publicvoidsilenceUpdateApp(Viewview) {
newUpdateAppManager
.Builder()
//当前Activity
.setActivity(this)
//更新地址
.setUpdateUrl(mUpdateUrl)
//实现httpManager接口的对象
.setHttpManager(newUpdateAppHttpUtil())
//只有wifi下进行,静默下载(只对静默下载有效)
.setOnlyWifi()
.build()
.silenceUpdate();
}
以下是使用默认协议的例子,也可以使用自定义协议(请参考自定义协议例子)
/** * 静默下载,并且自定义对话框 * * @param view */publicvoidsilenceUpdateAppAndDiyDialog(Viewview) {
newUpdateAppManager
.Builder()
//当前Activity
.setActivity(this)
//更新地址
.setUpdateUrl(mUpdateUrl)
//实现httpManager接口的对象
.setHttpManager(newUpdateAppHttpUtil())
//只有wifi下进行,静默下载(只对静默下载有效)
.setOnlyWifi()
.build()
.checkNewApp(newSilenceUpdateCallback() {
@OverrideprotectedvoidshowDialog(UpdateAppBeanupdateApp, UpdateAppManagerupdateAppManager, FileappFile) {
showSilenceDiyDialog(updateApp, appFile);
}
});
}
/** * 静默下载自定义对话框 * * @param updateApp * @param appFile */privatevoidshowSilenceDiyDialog(finalUpdateAppBeanupdateApp, finalFileappFile) {
StringtargetSize = updateApp.getTargetSize();
StringupdateLog = updateApp.getUpdateLog();
Stringmsg = "";
if (!TextUtils.isEmpty(targetSize)) {
msg = "新版本大小:" + targetSize + "\n\n";
}
if (!TextUtils.isEmpty(updateLog)) {
msg += updateLog;
}
newAlertDialog.Builder(this)
.setTitle(String.format("是否升级到%s版本?", updateApp.getNewVersion()))
.setMessage(msg)
.setPositiveButton("安装", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterfacedialog, intwhich) {
AppUpdateUtils.installApp(JavaActivity.this, appFile);
dialog.dismiss();
}
})
.setNegativeButton("暂不升级", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterfacedialog, intwhich) {
dialog.dismiss();
}
})
.create()
.show();
}UpdateAppBeanupdateAppBean = newUpdateAppBean();
//设置 apk 的下载地址updateAppBean.setApkFileUrl("https://raw.githubusercontent.com/WVector/AppUpdateDemo/master/apk/app-debug.apk");
Stringpath = "";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) || !Environment.isExternalStorageRemovable()) {
try {
path = getExternalCacheDir().getAbsolutePath();
} catch (Exceptione) {
e.printStackTrace();
}
if (TextUtils.isEmpty(path)) {
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
}
} else {
path = getCacheDir().getAbsolutePath();
}
//设置apk 的保存路径updateAppBean.setTargetPath(path);
//实现网络接口,只实现下载就可以updateAppBean.setHttpManager(newUpdateAppHttpUtil());
UpdateAppManager.download(this, updateAppBean, newDownloadService.DownloadCallback() {
@OverridepublicvoidonStart() {
HProgressDialogUtils.showHorizontalProgressDialog(JavaActivity.this, "下载进度", false);
Log.d(TAG, "onStart() called");
}
@OverridepublicvoidonProgress(floatprogress, longtotalSize) {
HProgressDialogUtils.setProgress(Math.round(progress * 100));
Log.d(TAG, "onProgress() called with: progress = [" + progress + "], totalSize = [" + totalSize + "]");
}
@OverridepublicvoidsetMax(longtotalSize) {
Log.d(TAG, "setMax() called with: totalSize = [" + totalSize + "]");
}
@OverridepublicbooleanonFinish(Filefile) {
HProgressDialogUtils.cancel();
Log.d(TAG, "onFinish() called with: file = [" + file.getAbsolutePath() + "]");
returntrue;
}
@OverridepublicvoidonError(Stringmsg) {
HProgressDialogUtils.cancel();
Log.e(TAG, "onError() called with: msg = [" + msg + "]");
}
@OverridepublicbooleanonInstallAppAndAppOnForeground(Filefile) {
Log.d(TAG, "onInstallAppAndAppOnForeground() called with: file = [" + file + "]");
returnfalse;
}
});根据自己项目使用的网络框架,自己实现HttpManager接口
classUpdateAppHttpUtilimplementsHttpManager {
/** * 异步get * * @param url get请求地址 * @param params get参数 * @param callBack 回调 */@OverridepublicvoidasyncGet(@NonNullStringurl, @NonNullMap<String, String> params, @NonNullfinalCallbackcallBack) {
OkHttpUtils.get()
.url(url)
.params(params)
.build()
.execute(newStringCallback() {
@OverridepublicvoidonError(Callcall, Responseresponse, Exceptione, intid) {
callBack.onError(validateError(e, response));
}
@OverridepublicvoidonResponse(Stringresponse, intid) {
callBack.onResponse(response);
}
});
}
/** * 异步post * * @param url post请求地址 * @param params post请求参数 * @param callBack 回调 */@OverridepublicvoidasyncPost(@NonNullStringurl, @NonNullMap<String, String> params, @NonNullfinalCallbackcallBack) {
OkHttpUtils.post()
.url(url)
.params(params)
.build()
.execute(newStringCallback() {
@OverridepublicvoidonError(Callcall, Responseresponse, Exceptione, intid) {
callBack.onError(validateError(e, response));
}
@OverridepublicvoidonResponse(Stringresponse, intid) {
callBack.onResponse(response);
}
});
}
/** * 下载 * * @param url 下载地址 * @param path 文件保存路径 * @param fileName 文件名称 * @param callback 回调 */@Overridepublicvoiddownload(@NonNullStringurl, @NonNullStringpath, @NonNullStringfileName, @NonNullfinalFileCallbackcallback) {
OkHttpUtils.get()
.url(url)
.build()
.execute(newFileCallBack(path, fileName) {
@OverridepublicvoidinProgress(floatprogress, longtotal, intid) {
super.inProgress(progress, total, id);
callback.onProgress(progress, total);
}
@OverridepublicvoidonError(Callcall, Responseresponse, Exceptione, intid) {
callback.onError(validateError(e, response));
}
@OverridepublicvoidonResponse(Fileresponse, intid) {
callback.onResponse(response);
}
@OverridepublicvoidonBefore(Requestrequest, intid) {
super.onBefore(request, id);
callback.onBefore();
}
});
}
}