先上个效果图大家看看
上面就是整个的跟新流程了,如果你真好要做这种欢迎使用
1.下面开始介绍一下代码的流程,原理很简单希望对大家会有帮助
首先是代码的编写逻辑
访问服务器的接口获取版本后台版本信息和前台对比判断是都需要更新,如需要弹出如图的提示框,我这里有相关的强制更新的 内容在里面,这里就不做详细说明了。
2.下面是代码的整体流程了,首先就是从连接开始走,下面是代码
public void showUpdateUI(final UpdateBean updateInfo, Boolean isConstraint) {
//这里这个参数是区分是否强制更新的标记,其实两部分代码基本一致
if (isConstraint) {//下面是更新对话框
final ConstraintUpdateVersionDialog updateVersionDialog = new ConstraintUpdateVersionDialog(
mContext, R.style.myDialogTheme,
new ConstraintUpdateVersionDialogListener() {
@Override
public void OnOkButtonClicked(
ConstraintUpdateVersionDialog dialog) {
// 更新项目,简单判断
if (StringUtil.isEmpty(updateInfo.data.downAdr)) {
Toast.makeText(mContext, "没有下载地址",
Toast.LENGTH_SHORT).show();
// dialog.dismiss();
return;
}
if (!updateInfo.data.downAdr.contains("http://")) {
Toast.makeText(mContext, "下载地址出错",
Toast.LENGTH_SHORT).show();
// dialog.dismiss();
return;
}
NetUtils netWorkUtils = new NetUtils(mContext);
int type = netWorkUtils.getNetType();
if (type != 1) {
showNetDialog(updateInfo);
} else {
AsyncDownLoad asyncDownLoad = new AsyncDownLoad();
asyncDownLoad.execute(updateInfo);
}
// dialog.dismiss(); 这里是要让对话框不消失,达到强制用户更新的目的,并且
//屏蔽了返回按键
}
@Override
public void OnCancelButtonClicked(
ConstraintUpdateVersionDialog dialog) {
dialog.dismiss();
AppManager.getAppManager().AppExit(mContext);
}
});
updateVersionDialog.setCancelable(false);
updateVersionDialog.setVersionsNumberStr(updateInfo.data.version);
updateVersionDialog.setUpdateContentStr(updateInfo.data.contexts);
updateVersionDialog.show();
} else {
final UpdateVersionDialog updateVersionDialog = new UpdateVersionDialog(
mContext, R.style.myDialogTheme,
new UpdateVersionDialogListener() {
@Override
public void OnOkButtonClicked(UpdateVersionDialog dialog) {
// 更新项目
if (StringUtil.isEmpty(updateInfo.data.downAdr)) {
Toast.makeText(mContext, "没有下载地址",
Toast.LENGTH_SHORT).show();
dialog.dismiss();
return;
}
if (!updateInfo.data.downAdr.contains("http://")) {
Toast.makeText(mContext, "下载地址出错",
Toast.LENGTH_SHORT).show();
dialog.dismiss();
return;
}
NetUtils netWorkUtils = new NetUtils(mContext);
int type = netWorkUtils.getNetType();
if (type != 1) {
showNetDialog(updateInfo);
} else {
AsyncDownLoad asyncDownLoad = new AsyncDownLoad();
asyncDownLoad.execute(updateInfo);
}
dialog.dismiss();
}
@Override
public void OnCancelButtonClicked(
UpdateVersionDialog dialog) {
dialog.dismiss();
}
});
updateVersionDialog.setVersionsNumberStr("版本号:"
+ updateInfo.data.version);
updateVersionDialog.setUpdateContentStr(updateInfo.data.contexts);
updateVersionDialog.show();
}
}
3.下面是到比较重要的下载环节中,这里主要在子线程中,主要是更新进度的时候要注意信息发送的频次(掉坑了
![尴尬](http://static.blog.csdn.net/xheditor/xheditor_emot/default/awkward.gif)
/**
* 异步下载app任务
*/
private class AsyncDownLoad extends AsyncTask<UpdateBean, Integer, Boolean> {
@Override
protected Boolean doInBackground(final UpdateBean... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(params[0].data.downAdr);
try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// Looper.prepare();
// Toast.makeText(mContext,
// "APK路径出错,请检查服务端配置接口",Toast.LENGTH_SHORT).show();
// Looper.loop();
// System.out.println("APK路径出错,请检查服务端配置接口");
return false;
} else {
/*------*/
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
long total = entity.getContentLength();
String apkName = APPNAME + SUFFIX;
File savePath = new File(PATH);
cache.put(APP_NAME, APPNAME);
cache.put(APK_PATH, savePath + File.separator + apkName);
if (!savePath.exists())
savePath.mkdirs();
File apkFile = new File(savePath + File.separator + apkName);
if (apkFile.exists()) {
apkFile.delete();
}
FileOutputStream fos = new FileOutputStream(apkFile);
byte[] buf = new byte[1024];
int count = 0;
int length = -1;
float progress = 0;
while ((length = inputStream.read(buf)) != -1) {
fos.write(buf, 0, length);
count += length;
int temp = (int) ((count / (float) total) * 100);
if (temp - progress > 1) {
progress = temp;
System.out.println("执行多少次呢");
handler.obtainMessage(UPDATE_NOTIFICATION_PROGRESS,
(int) progress, -1, params[0])
.sendToTarget();
System.out.println(progress
+ "-----------------------------");
}
if (UpdateHelper.this.updateListener != null) {
UpdateHelper.this.updateListener
.onDownloading((int) progress);
}
}
inputStream.close();
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean flag) {
if (flag) {//下载完成后发送安装消息
<pre name="code" class="java"> handler.obtainMessage(COMPLETE_DOWNLOAD_APK).sendToTarget();
if (UpdateHelper.this.updateListener != null) {UpdateHelper.this.updateListener.onFinshDownload();}} else {Toast.makeText(mContext, "下载失败", Toast.LENGTH_LONG).show();}}}
4.这里开始去更新进度条的内容了。
private Handler handler = new Handler() {
@Override
public void handleMessage(final Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case UPDATE_NOTIFICATION_PROGRESS:
//展示ui
showDownloadNotificationUI((UpdateBean) msg.obj, msg.arg1);
break;
case COMPLETE_DOWNLOAD_APK://下载完成后发送安装消息
if (UpdateHelper.this.isAutoInstall) {
installApk(Uri.parse("file://" + cache.get(APK_PATH)));
} else {
if (ntfBuilder == null) {
ntfBuilder = new NotificationCompat.Builder(mContext);
}
ntfBuilder.setSmallIcon(mContext.getApplicationInfo().icon)
.setContentTitle(cache.get(APP_NAME))
.setContentText("下载完成,点击安装").setTicker("任务下载完成");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + cache.get(APK_PATH)),
"application/vnd.android.package-archive");
PendingIntent pendingIntent = PendingIntent.getActivity(
mContext, 0, intent, 0);
ntfBuilder.setContentIntent(pendingIntent);
if (notificationManager == null) {
notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
}
notificationManager.notify(DOWNLOAD_NOTIFICATION_ID,
ntfBuilder.build());
}
break;
}
}
};
5.下面Notification的内容编写就不多说明了
private void showDownloadNotificationUI(UpdateBean bean, final int progress) {
if (mContext != null) {
String contentText = new StringBuffer().append(APPNAME + " ")
.append(progress).append("%").toString();
PendingIntent contentIntent = PendingIntent.getActivity(mContext,
0, new Intent(), PendingIntent.FLAG_CANCEL_CURRENT);
if (notificationManager == null) {
notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (ntfBuilder == null) {
ntfBuilder = new NotificationCompat.Builder(mContext)
.setSmallIcon(mContext.getApplicationInfo().icon)
.setTicker("开始下载...").setContentIntent(contentIntent);
}
ntfBuilder.setContentText(contentText);
ntfBuilder.setProgress(100, progress, false);
notificationManager.notify(DOWNLOAD_NOTIFICATION_ID,
ntfBuilder.build());
}
}
6.安装应用,就是跳转到系统的安装界面了,下面是需要知道的
// 安装
private void installApk(Uri data) {
if (mContext != null) {
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);
if (notificationManager != null) {
notificationManager.cancel(DOWNLOAD_NOTIFICATION_ID);
}
} else {
Toast.makeText(mContext, "找不到安装文件", Toast.LENGTH_LONG).show();
}
}
总结:基本的流程就是这样子了,并没有多大的难度,主要是要注意更新ui的那个地方,希望能帮助有需求的同学,要是有什么问题欢迎留言