本文实例讲述了Android程序自动更新功能模块的实现方法。分享给大家供大家参考,具体如下:

在程序启动的时候检测服务器上有没有对应版本更新,如果有更新,提示用户是否更新。

在程序启动的时候首先调用更新模块检测服务器上存放的版本号跟当前程序的版本号如果大于当前版本号,弹出更新对话框,如果用户选择更新,则显示当前更新状态,然后替换当前程序。

程序调用版本更新检测:

private UpdateManager updateMan;

private ProgressDialog updateProgressDialog;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//没有判断网路是否连接

//检查是否有更新

//如果有更新提示下载

updateMan = new UpdateManager(Update_TestActivity.this, appUpdateCb);

updateMan.checkUpdate();

}

执行检测版本号以及回调更新提示

下载更新文件等实现:

package update.test;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import org.json.JSONArray;

import org.json.JSONObject;

import com.trinet.util.NetHelper;

import android.content.Context;

import android.content.Intent;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager.NameNotFoundException;

import android.net.Uri;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

public class UpdateManager {

private String curVersion;

private String newVersion;

private int curVersionCode;

private int newVersionCode;

private String updateInfo;

private UpdateCallback callback;

private Context ctx;

private int progress;

private Boolean hasNewVersion;

private Boolean canceled;

//存放更新APK文件的路径

public static final String UPDATE_DOWNURL = "http://www.baidu.com/update/update_test.apk";

//存放更新APK文件相应的版本说明路径

public static final String UPDATE_CHECKURL = "http://www.baidu.com/update/update_verson.txt";

public static final String UPDATE_APKNAME = "update_test.apk";

//public static final String UPDATE_VERJSON = "ver.txt";

public static final String UPDATE_SAVENAME = "updateapk.apk";

private static final int UPDATE_CHECKCOMPLETED = 1;

private static final int UPDATE_DOWNLOADING = 2;

private static final int UPDATE_DOWNLOAD_ERROR = 3;

private static final int UPDATE_DOWNLOAD_COMPLETED = 4;

private static final int UPDATE_DOWNLOAD_CANCELED = 5;

//从服务器上下载apk存放文件夹

private String savefolder = "/mnt/innerDisk/";

//private String savefolder = "/sdcard/";

//public static final String SAVE_FOLDER =Storage. // "/mnt/innerDisk";

public UpdateManager(Context context, UpdateCallback updateCallback) {

ctx = context;

callback = updateCallback;

//savefolder = context.getFilesDir();

canceled = false;

getCurVersion();

}

public String getNewVersionName()

{

return newVersion;

}

public String getUpdateInfo()

{

return updateInfo;

}

private void getCurVersion() {

try {

PackageInfo pInfo = ctx.getPackageManager().getPackageInfo(

ctx.getPackageName(), 0);

curVersion = pInfo.versionName;

curVersionCode = pInfo.versionCode;

} catch (NameNotFoundException e) {

Log.e("update", e.getMessage());

curVersion = "1.1.1000";

curVersionCode = 111000;

}

}

public void checkUpdate() {

hasNewVersion = false;

new Thread(){

// ***************************************************************

/**

* @by wainiwann

*

*/

@Override

public void run() {

Log.i("@@@@@", ">>>>>>>>>>>>>>>>>>>>>>>>>>>getServerVerCode() ");

try {

String verjson = NetHelper.httpStringGet(UPDATE_CHECKURL);

Log.i("@@@@", verjson

+ "**************************************************");

JSONArray array = new JSONArray(verjson);

if (array.length() > 0) {

JSONObject obj = array.getJSONObject(0);

try {

newVersionCode = Integer.parseInt(obj.getString("verCode"));

newVersion = obj.getString("verName");

updateInfo = "";

Log.i("newVerCode", newVersionCode

+ "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

Log.i("newVerName", newVersion

+ "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

if (newVersionCode > curVersionCode) {

hasNewVersion = true;

}

} catch (Exception e) {

newVersionCode = -1;

newVersion = "";

updateInfo = "";

}

}

} catch (Exception e) {

Log.e("update", e.getMessage());

}

updateHandler.sendEmptyMessage(UPDATE_CHECKCOMPLETED);

};

// ***************************************************************

}.start();

}

public void update() {

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.setDataAndType(

Uri.fromFile(new File(savefolder, UPDATE_SAVENAME)),

"application/vnd.android.package-archive");

ctx.startActivity(intent);

}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

public void downloadPackage()

{

new Thread() {

@Override

public void run() {

try {

URL url = new URL(UPDATE_DOWNURL);

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.connect();

int length = conn.getContentLength();

InputStream is = conn.getInputStream();

File ApkFile = new File(savefolder,UPDATE_SAVENAME);

if(ApkFile.exists())

{

ApkFile.delete();

}

FileOutputStream fos = new FileOutputStream(ApkFile);

int count = 0;

byte buf[] = new byte[512];

do{

int numread = is.read(buf);

count += numread;

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

updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOADING));

if(numread <= 0){

updateHandler.sendEmptyMessage(UPDATE_DOWNLOAD_COMPLETED);

break;

}

fos.write(buf,0,numread);

}while(!canceled);

if(canceled)

{

updateHandler.sendEmptyMessage(UPDATE_DOWNLOAD_CANCELED);

}

fos.close();

is.close();

} catch (MalformedURLException e) {

e.printStackTrace();

updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOAD_ERROR,e.getMessage()));

} catch(IOException e){

e.printStackTrace();

updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOAD_ERROR,e.getMessage()));

}

}

}.start();

}

public void cancelDownload()

{

canceled = true;

}

Handler updateHandler = new Handler()

{

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case UPDATE_CHECKCOMPLETED:

callback.checkUpdateCompleted(hasNewVersion, newVersion);

break;

case UPDATE_DOWNLOADING:

callback.downloadProgressChanged(progress);

break;

case UPDATE_DOWNLOAD_ERROR:

callback.downloadCompleted(false, msg.obj.toString());

break;

case UPDATE_DOWNLOAD_COMPLETED:

callback.downloadCompleted(true, "");

break;

case UPDATE_DOWNLOAD_CANCELED:

callback.downloadCanceled();

default:

break;

}

}

};

public interface UpdateCallback {

public void checkUpdateCompleted(Boolean hasUpdate,

CharSequence updateInfo);

public void downloadProgressChanged(int progress);

public void downloadCanceled();

public void downloadCompleted(Boolean sucess, CharSequence errorMsg);

}

}

需要连接服务器模块:

package com.trinet.util;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.MalformedURLException;

import java.net.URI;

import java.net.URL;

import org.apache.http.HttpResponse;

import org.apache.http.client.HttpClient;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.params.CoreProtocolPNames;

import org.apache.http.params.HttpConnectionParams;

import org.apache.http.params.HttpParams;

import android.content.Context;

import android.graphics.drawable.Drawable;

import android.net.ConnectivityManager;

import android.net.NetworkInfo;

import android.util.Log;

public class NetHelper {

public static String httpStringGet(String url) throws Exception {

return httpStringGet(url, "utf-8");

}

/**

*

*

* @param url

* @return

*/

public static Drawable loadImage(String url) {

try {

return Drawable.createFromStream(

(InputStream) new URL(url).getContent(), "test");

} catch (MalformedURLException e) {

Log.e("exception", e.getMessage());

} catch (IOException e) {

Log.e("exception", e.getMessage());

}

return null;

}

public static String httpStringGet(String url, String enc) throws Exception {

// This method for HttpConnection

String page = "";

BufferedReader bufferedReader = null;

try {

HttpClient client = new DefaultHttpClient();

client.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "android");

HttpParams httpParams = client.getParams();

HttpConnectionParams.setConnectionTimeout(httpParams, 3000);

HttpConnectionParams.setSoTimeout(httpParams, 5000);

HttpGet request = new HttpGet();

request.setHeader("Content-Type", "text/plain; charset=utf-8");

request.setURI(new URI(url));

HttpResponse response = client.execute(request);

bufferedReader = new BufferedReader(new InputStreamReader(response

.getEntity().getContent(), enc));

StringBuffer stringBuffer = new StringBuffer("");

String line = "";

String NL = System.getProperty("line.separator");

while ((line = bufferedReader.readLine()) != null) {

stringBuffer.append(line + NL);

}

bufferedReader.close();

page = stringBuffer.toString();

Log.i("page", page);

System.out.println(page + "page");

return page;

} finally {

if (bufferedReader != null) {

try {

bufferedReader.close();

} catch (IOException e) {

Log.d("BBB", e.toString());

}

}

}

}

public static boolean checkNetWorkStatus(Context context) {

boolean result;

ConnectivityManager cm = (ConnectivityManager) context

.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo netinfo = cm.getActiveNetworkInfo();

if (netinfo != null && netinfo.isConnected()) {

result = true;

Log.i("NetStatus", "The net was connected");

} else {

result = false;

Log.i("NetStatus", "The net was bad!");

}

return result;

}

}

以及提示对话框:

package com.trinet.util;

import java.lang.reflect.Field;

import android.app.AlertDialog;

import android.app.AlertDialog.Builder;

import android.content.Context;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.view.View;

public class DialogHelper {

public static void Alert(Context ctx, CharSequence title, CharSequence message,

CharSequence okText, OnClickListener oklistener) {

AlertDialog.Builder builder = createDialog(ctx, title, message);

builder.setPositiveButton(okText, oklistener);

builder.create().show();

}

public static void Alert(Context ctx, int titleId, int messageId,

int okTextId, OnClickListener oklistener) {

Alert(ctx, ctx.getText(titleId), ctx.getText(messageId), ctx.getText(okTextId), oklistener);

}

public static void Confirm(Context ctx, CharSequence title, CharSequence message,

CharSequence okText, OnClickListener oklistener, CharSequence cancelText,

OnClickListener cancellistener) {

AlertDialog.Builder builder = createDialog(ctx, title, message);

builder.setPositiveButton(okText, oklistener);

builder.setNegativeButton(cancelText, cancellistener);

builder.create().show();

}

public static void Confirm(Context ctx, int titleId, int messageId,

int okTextId, OnClickListener oklistener, int cancelTextId,

OnClickListener cancellistener) {

Confirm(ctx, ctx.getText(titleId), ctx.getText(messageId), ctx.getText(okTextId), oklistener, ctx.getText(cancelTextId), cancellistener);

}

private static AlertDialog.Builder createDialog(Context ctx, CharSequence title,

CharSequence message) {

AlertDialog.Builder builder = new Builder(ctx);

builder.setMessage(message);

if(title!=null)

{

builder.setTitle(title);

}

return builder;

}

@SuppressWarnings("unused")

private static AlertDialog.Builder createDialog(Context ctx,int titleId, int messageId) {

AlertDialog.Builder builder = new Builder(ctx);

builder.setMessage(messageId);

builder.setTitle(titleId);

return builder;

}

public static void ViewDialog(Context ctx, CharSequence title, View view,

CharSequence okText, OnClickListener oklistener, CharSequence cancelText,

OnClickListener cancellistener) {

}

public static void ViewDialog(Context ctx, int titleId, View view,

int okTextId, OnClickListener oklistener, int cancelTextId,

OnClickListener cancellistener) {

ViewDialog(ctx, ctx.getText(titleId), view, ctx.getText(okTextId), oklistener, ctx.getText(cancelTextId), cancellistener);

}

//

public static void SetDialogShowing(DialogInterface dialog, boolean showing)

{

try {

Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");

field.setAccessible(true);

field.set(dialog, showing);

} catch (Exception e) {

e.printStackTrace();

}

}

}

下面是又更新的话执行回调函数提示用户:

// 自动更新回调函数

UpdateManager.UpdateCallback appUpdateCb = new UpdateManager.UpdateCallback()

{

public void downloadProgressChanged(int progress) {

if (updateProgressDialog != null

&& updateProgressDialog.isShowing()) {

updateProgressDialog.setProgress(progress);

}

}

public void downloadCompleted(Boolean sucess, CharSequence errorMsg) {

if (updateProgressDialog != null

&& updateProgressDialog.isShowing()) {

updateProgressDialog.dismiss();

}

if (sucess) {

updateMan.update();

} else {

DialogHelper.Confirm(Update_TestActivity.this,

R.string.dialog_error_title,

R.string.dialog_downfailed_msg,

R.string.dialog_downfailed_btnnext,

new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog,

int which) {

updateMan.downloadPackage();

}

}, R.string.dialog_downfailed_btnnext, null);

}

}

public void downloadCanceled()

{

// TODO Auto-generated method stub

}

public void checkUpdateCompleted(Boolean hasUpdate,

CharSequence updateInfo) {

if (hasUpdate) {

DialogHelper.Confirm(Update_TestActivity.this,

getText(R.string.dialog_update_title),

getText(R.string.dialog_update_msg).toString()

+updateInfo+

getText(R.string.dialog_update_msg2).toString(),

getText(R.string.dialog_update_btnupdate),

new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog,

int which) {

updateProgressDialog = new ProgressDialog(

Update_TestActivity.this);

updateProgressDialog

.setMessage(getText(R.string.dialog_downloading_msg));

updateProgressDialog.setIndeterminate(false);

updateProgressDialog

.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

updateProgressDialog.setMax(100);

updateProgressDialog.setProgress(0);

updateProgressDialog.show();

updateMan.downloadPackage();

}

},getText( R.string.dialog_update_btnnext), null);

}

}

};

要记得给程序添加权限:

完整实例代码点击此处本站下载。

希望本文所述对大家Android程序设计有所帮助。

android自动更新demo,Android程序自动更新功能模块的实现方法【附完整demo源码下载】...相关推荐

  1. 外卖返利小程序公众号美团饿了么返利系统完整PHP源码下载

    无需域名,一键授权公众号 多级分销,代理推广赚钱 自定义代理佣金比例 自定义联盟账号 商品自动同步,订单自动跟踪 优秀交互体验,快速上手 淘客老牌猎客团队精心打磨,精美UI 支持多公众号数据互通,矩阵 ...

  2. 最新仿淘宝B站购物直播小程序+带货完整PHP源码下载

    正文: 最新仿淘宝B站购物直播小程序+带货完整PHP源码下载,由于演示图太长了,所以我分别载图了两张,完整的演示图直接发压缩包了,有兴趣自行去查看. 当前版本已经修复直播间相关的一些BUG,还有商品新 ...

  3. 小程序功能模块-优客娱乐视频1.0.5源码

    简介: 客娱乐视频是一款支持在线采集的在线视频给公众号系统, 同时支持H5在线播放,支持认证的订阅号.认证服务号, 如果没有也可以使用H5浏览器.QQ等打开,怎么使用都行. 特色功能: 01 支持炮灰 ...

  4. 【整站程序】wordpress-RiPro-V2去授权WordPress主题虚拟收费主题源码下载

    [整站程序]RiPro-V2去授权WordPress主题RiPlus虚拟收费主题源码下载RiPro-V2是一个优秀的主题,首页拖拽布局,高级筛选,自带会员生态系统,超全支付接口,你喜欢的样子我都有!R ...

  5. Android音频实时传输与播放(四):源码下载(问题更新)【转】

    Android音频实时传输与播放(四):源码下载(问题更新) 激动人心的时刻到了有木有 ^_^ 服务端下载请点击这里,客户端下载请点击这里! 最近有朋友在下载源码使用之后,说播放出来的声音噪声很大.其 ...

  6. (已更新)王者荣耀改名神器助手微信小程序源码下载

    这是一个强大的改名神器,强大的生成功能 输入您想要制作的名字可以一键生成N个重复名供您选择 这样就不用担心有些重复名被别人使用了导致无法使用 另外还有英雄昵称,提供多种昵称分类自动生成 比如情侣名字, ...

  7. 表情包壁纸独立后台美化二开版本新增加神器功能微信小程序源码下载+教程自动采集

    相信玩小程序的朋友对这款小程序应该也不陌生 这是前半年很火的一款微信表情包小程序功能 之前的版本内置了表情包还有壁纸功能 这一期的版本给优化了一下UI和新增加了一些喝酒神器功能 具体新增加的喝酒神器功 ...

  8. (已更新)多分类经典语录微信小程序源码下载支持一键复制带壁纸,王者改名等功能

    这是一款主要以各类语录分享的一款小程序源码 比如有:舔狗日记,土味情话,别味情话,励志鸡汤 内容支持一键复制分享,可以随时切换下一个内容 另外还有壁纸功能(属于自动采集) 还有王者荣耀空白名修改,重复 ...

  9. 纯头像微信小程序源码下载,多分类头像自动采集

    这是一款纯头像的微信小程序 除了头像没有其它功能 头像有多种分类,功能简洁实用 另外该小程序无需服务器和域名 该小程序安装方法如下: 解压域名以后然后使用微信开发者工具打开该小程序源码 然后配置一下合 ...

最新文章

  1. 弹性分组环(RPR)技术特点及其在城域网中的应用
  2. fitnesse页面增加认证
  3. 从 C++ 到 Objective-C 的快速指南 【已翻译100%】
  4. a标签href不跳转_[网页编程]-06 HTML5 超链接标签
  5. 安卓APP_ Fragment(5)—— Fragment + ViewPager2 模拟微信首页 (2)两者联动翻页
  6. scanner close_Java Scanner close()方法与示例
  7. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
  8. Laravel服务提供器
  9. java httpclient 返回xml_通过httpClient通过post向接口发送xml数据,并处理返回的xml报文...
  10. 微软首席技术官:不清楚平板是否昙花一现
  11. [AHK]从QQ音乐网站下载歌曲
  12. 数据库实验五-数据库设计实验
  13. 小技巧——cmd杀手进程
  14. 联通loid认证_光纤LOID 认证 需要填写的用户名是什么?有人说不...
  15. HTML5教程|0代码,快速制作调查问卷
  16. Ubuntu内网穿透搭建网站:设置跳转本地网页服务 6/17
  17. 【ibokan】SEO个人笔记+百度百科详细介绍
  18. 计算机更改用户后 无法联网,为什么重置密码后路由器无法上网
  19. jfinal 生成实体类
  20. 数据告诉你,火锅为什么能成为聚餐的首选

热门文章

  1. 发送邮件(注册用户并激活邮箱)
  2. Centos修改默认网卡名
  3. 『C#基础』C#导出Excel
  4. Bailian2703 骑车与走路【水题】
  5. 2019ICPC亚洲区域赛日程与2019CCPC比赛日程
  6. AOJ0008 Sum of 4 Integers【暴力】
  7. Bailian2679 整数的立方和【入门】
  8. HDU1434 幸福列车【模拟+优先队列】
  9. HDU2096 小明A+B【水题】
  10. CCF201509-3 模板生成系统(100分)