图文课程 职群旗下

  1. 首页
  2. 所有分类
  3. 前端
  4. android应用版本更新功能---完整版

android应用版本更新功能---完整版

 

源码下载地址:csdn下载地址:http://download.csdn.net/download/csdn576038874/9526085

       博客园下载地址:http://files.cnblogs.com/files/wenjie123/updateversion.rar

1、检测是否有新版本

public class MainActivity extends Activity {private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button
= (Button) findViewById(R.id.button1);
button.setOnClickListener(
new OnClickListener() {@Overridepublic void onClick(View v) {
//
本地测试检测是否有新版本发布UpdateVersionUtil.localCheckedVersion(MainActivity.this,new UpdateListener() {@Overridepublic void onUpdateReturned(int updateStatus, VersionInfo versionInfo) {
//
判断回调过来的版本检测状态switch (updateStatus) {case UpdateStatus.YES:
//
弹出更新提示UpdateVersionUtil.showDialog(MainActivity.this,versionInfo);
break;
case UpdateStatus.NO:
//
没有新版本ToastUtils.showToast(getApplicationContext(), "已经是最新版本了!");
break;
case UpdateStatus.NOWIFI:
//
当前是非wifi网络ToastUtils.showToast(getApplicationContext(), "只有在wifi下更新!");

//
DialogUtils.showDialog(MainActivity.this, "温馨提示","当前非wifi网络,下载会消耗手机流量!", "确定", "取消",new DialogOnClickListenner() {
//
@Override
//
public void btnConfirmClick(Dialog dialog) {
//
dialog.dismiss();

//

//
点击确定之后弹出更新对话框
//
UpdateVersionUtil.showDialog(SystemActivity.this,versionInfo);

//
}


//

//
@Override
//
public void btnCancelClick(Dialog dialog) {
//
dialog.dismiss();

//
}


//
});break;
case UpdateStatus.ERROR:
//
检测失败ToastUtils.showToast(getApplicationContext(), "检测失败,请稍后重试!");
break;
case UpdateStatus.TIMEOUT:
//
链接超时ToastUtils.showToast(getApplicationContext(), "链接超时,请检查网络设置!");
break;
}

}

});

/**
*
//访问服务器 试检测是否有新版本发布UpdateVersionUtil.localCheckedVersion(MainActivity.this,new UpdateListener() {@Overridepublic void onUpdateReturned(int updateStatus, VersionInfo versionInfo) {
//判断回调过来的版本检测状态switch (updateStatus) {case UpdateStatus.YES:
//弹出更新提示UpdateVersionUtil.showDialog(MainActivity.this,versionInfo);
break;
case UpdateStatus.NO:
//没有新版本ToastUtils.showToast(getApplicationContext(), "已经是最新版本了!");
break;
case UpdateStatus.NOWIFI:
//当前是非wifi网络ToastUtils.showToast(getApplicationContext(), "只有在wifi下更新!");

//DialogUtils.showDialog(MainActivity.this, "温馨提示","当前非wifi网络,下载会消耗手机流量!", "确定", "取消",new DialogOnClickListenner() {
//@Override
//public void btnConfirmClick(Dialog dialog) {
//dialog.dismiss();

//
//点击确定之后弹出更新对话框
//UpdateVersionUtil.showDialog(SystemActivity.this,versionInfo);

//}


//
//@Override
//public void btnCancelClick(Dialog dialog) {
//dialog.dismiss();

//}


//});
break;
case UpdateStatus.ERROR:
//检测失败ToastUtils.showToast(getApplicationContext(), "检测失败,请稍后重试!");
break;
case UpdateStatus.TIMEOUT:
//链接超时ToastUtils.showToast(getApplicationContext(), "链接超时,请检查网络设置!");
break;
}

}

});
*/}

});
}

}

2、版本检测的工具类


/**
** @authorwenjie*版本更新的工具类*/public class UpdateVersionUtil{
/**
* 接口回调* @author wenjie**/public interface UpdateListener{void onUpdateReturned(int updateStatus,VersionInfo versionInfo);
}

public UpdateListener updateListener;
public void setUpdateListener(UpdateListener updateListener) {this.updateListener = updateListener;
}


/**
* 网络测试 检测版本* @param context 上下文*/public static void checkVersion(final Context context,final UpdateListener updateListener){HttpRequest.get(ServerReqAddress.UPDATA_VERSION_REQ, new RequestCallBackListener() {@Overridepublic void onSuccess(String resultData) {try {JSONObject jsonObject = JsonUtil.stringToJson(resultData);
JSONArray array
= jsonObject.getJSONArray("data");
VersionInfo mVersionInfo
= JsonUtil.jsonToBean(array.getJSONObject(0).toString(), VersionInfo.class);
int clientVersionCode = ApkUtils.getVersionCode(context);
int serverVersionCode = mVersionInfo.getVersionCode();

//
有新版本if(clientVersionCode < serverVersionCode){int i = NetworkUtil.checkedNetWorkType(context);
if(i == NetworkUtil.NOWIFI){updateListener.onUpdateReturned(UpdateStatus.NOWIFI,mVersionInfo);
}
else if(i == NetworkUtil.WIFI){updateListener.onUpdateReturned(UpdateStatus.YES,mVersionInfo);
}

}
else{
//
无新本updateListener.onUpdateReturned(UpdateStatus.NO,null);
}

}

catch (Exception e) {e.printStackTrace();
updateListener.onUpdateReturned(UpdateStatus.ERROR,
null);
}

}

@Override
public void onFailure(String error) {updateListener.onUpdateReturned(UpdateStatus.TIMEOUT,null);
}

});
}


/**
* 本地测试*/public static void localCheckedVersion(final Context context,final UpdateListener updateListener){try {
//
JSONObject jsonObject = JsonUtil.stringToJson(resultData);

//
JSONArray array = jsonObject.getJSONArray("data");

//
VersionInfo mVersionInfo = JsonUtil.jsonToBean(array.getJSONObject(0).toString(), VersionInfo.class);VersionInfo mVersionInfo = new VersionInfo();
mVersionInfo.setDownloadUrl(
"http:
//gdown.baidu.com/data/wisegame/57a788487345e938/QQ_358.apk");
mVersionInfo.setVersionDesc(
"\n更新内容:\n1、增加xxxxxxxxx功能\n2、增加xxxxxxxxx显示!\n3、用户界面优化!\n4、处理了xxxxxxxxBUG!");
mVersionInfo.setVersionCode(
2);
mVersionInfo.setVersionName(
"v2020");
mVersionInfo.setVersionSize(
"20.1M");
mVersionInfo.setId(
"1");
int clientVersionCode = ApkUtils.getVersionCode(context);
int serverVersionCode = mVersionInfo.getVersionCode();

//
有新版本if(clientVersionCode < serverVersionCode){int i = NetworkUtil.checkedNetWorkType(context);
if(i == NetworkUtil.NOWIFI){updateListener.onUpdateReturned(UpdateStatus.NOWIFI,mVersionInfo);
}
else if(i == NetworkUtil.WIFI){updateListener.onUpdateReturned(UpdateStatus.YES,mVersionInfo);
}

}
else{
//
无新本updateListener.onUpdateReturned(UpdateStatus.NO,null);
}

}

catch (Exception e) {e.printStackTrace();
updateListener.onUpdateReturned(UpdateStatus.ERROR,
null);
}

}


/**
* 弹出新版本提示* @param context 上下文* @param versionInfo 更新内容*/public static void showDialog(final Context context,final VersionInfo versionInfo){final Dialog dialog = new AlertDialog.Builder(context).create();
final File file = new File(SDCardUtils.getRootDirectory()+"/updateVersion/gdmsaec-app.apk");
dialog.setCancelable(
true);
//
可以用“返回键”取消dialog.setCanceledOnTouchOutside(false);
//
dialog.show();
View view
= LayoutInflater.from(context).inflate(R.layout.version_update_dialog, null);
dialog.setContentView(view);
final Button btnOk = (Button) view.findViewById(R.id.btn_update_id_ok);
Button btnCancel
= (Button) view.findViewById(R.id.btn_update_id_cancel);
TextView tvContent
= (TextView) view.findViewById(R.id.tv_update_content);
TextView tvUpdateTile
= (TextView) view.findViewById(R.id.tv_update_title);
final TextView tvUpdateMsgSize = (TextView) view.findViewById(R.id.tv_update_msg_size);
tvContent.setText(versionInfo.getVersionDesc());
tvUpdateTile.setText(
"最新版本:"+versionInfo.getVersionName());
if(file.exists() &&
file.getName().equals("gdmsaec-app.apk")){tvUpdateMsgSize.setText("新版本已经下载,是否安装?");
}
else{tvUpdateMsgSize.setText("新版本大小:"+versionInfo.getVersionSize());
}

btnOk.setOnClickListener(
new OnClickListener() {@Overridepublic void onClick(View v) {dialog.dismiss();
if(v.getId() == R.id.btn_update_id_ok){
//
新版本已经下载if(file.exists() &&
file.getName().equals("gdmsaec-app.apk")){Intent intent = ApkUtils.getInstallIntent(file);
context.startActivity(intent);
}
else{
//
没有下载,则开启服务下载新版本Intent intent = new Intent(context,UpdateVersionService.class);
intent.putExtra(
"downloadUrl", versionInfo.getDownloadUrl());
context.startService(intent);
}

}

}

});
btnCancel.setOnClickListener(
new OnClickListener() {@Overridepublic void onClick(View v) {dialog.dismiss();
}

});
}


/**
* 收起通知栏* @param context*/public static void collapseStatusBar(Context context) {try{Object statusBarManager = context.getSystemService("statusbar");
Method collapse;
if (Build.VERSION.SDK_INT <= 16){collapse = statusBarManager.getClass().getMethod("collapse");
}
else{collapse = statusBarManager.getClass().getMethod("collapsePanels");
}

collapse.invoke(statusBarManager);
}
catch (Exception localException){localException.printStackTrace();
}

}

}

3、版本检测的状态类


/**
** @author wenjie*检测版本的状态类*/public interface UpdateStatus {
/**
* 没有新版本*/public static int NO = 1;

/**
* 有新版本*/public static int YES = 2;

/**
* 链接超时*/public static int TIMEOUT = 3;

/**
* 没有wifi*/public static int NOWIFI = 4;

/**
* 数据解析出错*/public static int ERROR = -1;
}

4、版本更新的service


/**
** @author wenjie*下载新版本的服务类*/public class UpdateVersionService extends Service {private NotificationManager nm;
private Notification notification;

//
标题标识private int titleId = 0;

//
安装文件private File updateFile;
private static HttpHandler<File> httpHandler;
private HttpUtils httpUtils;
private long initTotal = 0;
//
文件的总长度@Overridepublic void onCreate() {super.onCreate();
httpUtils
= new HttpUtils();
updateFile
= new File(SDCardUtils.getRootDirectory()+"/updateVersion/gdmsaec-app.apk");
nm
= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notification
= new Notification();
notification.icon
= R.drawable.ic_launcher;
notification.tickerText
= "开始下载";
notification.when
= System.currentTimeMillis();
notification.contentView
= new RemoteViews(getPackageName(), R.layout.notifycation);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//
VersionInfo versionInfo = (VersionInfo) intent.getSerializableExtra("versionInfo");

//
String url = versionInfo.getDownloadUrl();Bundle bundle = intent.getExtras();
String url
= bundle.getString("downloadUrl");
PreferenceUtils.setString(UpdateVersionService.
this, "apkDownloadurl", url);
nm.notify(titleId, notification);
downLoadFile(url);
return super.onStartCommand(intent, flags, startId);
}

public void downLoadFile(String url){httpHandler = httpUtils.download(url,updateFile.getAbsolutePath(), true, false, new RequestCallBack<File>() {@Overridepublic void onSuccess(ResponseInfo<File> response) {
//
更改文字notification.contentView.setTextViewText(R.id.msg, "下载完成!点击安装");

//
notification.contentView.setViewVisibility(R.id.btnStartStop, View.GONE);

//
notification.contentView.setViewVisibility(R.id.btnCancel,View.GONE);

//
发送消息nm.notify(0, notification);
stopSelf();

//
收起通知栏UpdateVersionUtil.collapseStatusBar(UpdateVersionService.this);

//
自动安装新版本Intent installIntent = ApkUtils.getInstallIntent(updateFile);
startActivity(installIntent);
}

@Override
public void onFailure(HttpException error, String msg) {
//
网络连接错误if(error.getExceptionCode() == 0 ){
//
更改文字notification.contentView.setTextViewText(R.id.msg, "网络异常!请检查网络设置!");
}
else if(error.getExceptionCode() == 416){
//
文件已经下载完毕
//
更改文字notification.contentView.setTextViewText(R.id.msg, "xxx");

//
更改文字notification.contentView.setTextViewText(R.id.bartext, "检测到新版本已经下载完成,点击即安装!");

//
隐藏进度条notification.contentView.setViewVisibility(R.id.progressBar1, View.GONE);
Intent intent
= ApkUtils.getInstallIntent(updateFile);
PendingIntent pendingIntent
= PendingIntent.getActivity(UpdateVersionService.this, 0, intent, 0);
notification.flags
= Notification.FLAG_AUTO_CANCEL;
//
点击通知栏之后 消失notification.contentIntent= pendingIntent;
//
启动指定意图 }


//
发送消息nm.notify(0, notification);
}

@Override
public void onLoading(long total, long current, boolean isUploading) {if(initTotal == 0){
//
说明第一次开始下载initTotal = total;
}

if(initTotal != total){
//
说明下载过程中暂停过,文件的总长度出现问题就把初始的文件的长度赋值给他重新计算已经下载的比例total = initTotal;
}

long l = current*100/total;
notification.contentView.setTextViewText(R.id.msg,
"正在下载:xxx");

//
更改文字notification.contentView.setTextViewText(R.id.bartext, l+ "%");

//
更改进度条notification.contentView.setProgressBar(R.id.progressBar1, 100,(int)l, false);

//
发送消息nm.notify(0, notification);

//
Intent intent = new Intent();

//
intent.setAction("cancel");

//
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);

//
notification.contentView.setOnClickPendingIntent(R.id.btnStartStop, pendingIntent);}

@Override
public void onStart() {notification.contentView.setTextViewText(R.id.msg, "开始下载:智慧海事");
nm.notify(titleId, notification);
}

});
}

public static HttpHandler<File> getHandler(){return httpHandler;
}

@Override
public void onDestroy() {
//
下载完成时,清楚该通知,自动安装nm.cancel(titleId);
System.out.println(
"UpdateVersionService----onDestroy");

//
try {
//
GdmsaecApplication.db.deleteAll(VersionInfo.class);

//
}

catch (DbException e) {

//
e.printStackTrace();

//
}super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {return null;
}

}

5、吐司的工具类

public class ToastUtils { private static String oldMsg;
protected static Toast toast= null;
private static long oneTime=0;
private static long twoTime=0;

/**
* 吐出一个显示时间较短的提示* @param context 上下文* @param s文本内容*/public static void showToast(Context context, String s){if(toast==null){toast =Toast.makeText(context, s, Toast.LENGTH_SHORT);
toast.show();
oneTime
=System.currentTimeMillis();
}
else{ twoTime=System.currentTimeMillis();
if(s.equals(oldMsg)){if(twoTime-oneTime>Toast.LENGTH_SHORT){toast.show();
}

}
else{oldMsg = s;
toast.setText(s);
toast.show();
}

}

oneTime
=twoTime;
}

}

6、获取sdcard根目录

public static String getState(){return Environment.getExternalStorageState();
}


/**
* SD卡是否可用* @return 只有当SD卡已经安装并且准备好了才返回true*/public static boolean isAvailable(){return getState().equals(Environment.MEDIA_MOUNTED);
}


/**
* 获取SD卡的根目录* @return null:不存在SD卡*/public static File getRootDirectory(){return isAvailable()?Environment.getExternalStorageDirectory():null;
}

7、版本检测的实体类

public class VersionInfo implements Serializable{
/**
**/private static final long serialVersionUID = 1L;
private String id;
private StringversionName;
//
版本名private intversionCode;
//
版本号private StringversionDesc;
//
版本描述信息内容private StringdownloadUrl;
//
新版本的下载路径private String versionSize;
//
版本大小public String getId() {return id;
}

public void setId(String id) {this.id = id;
}

public String getVersionSize() {return versionSize;
}

public void setVersionSize(String versionSize) {this.versionSize = versionSize;
}

public String getVersionName() {return versionName;
}

public void setVersionName(String versionName) {this.versionName = versionName;
}

public int getVersionCode() {return versionCode;
}

public void setVersionCode(int versionCode) {this.versionCode = versionCode;
}

public String getVersionDesc() {return versionDesc;
}

public void setVersionDesc(String versionDesc) {this.versionDesc = versionDesc;
}

public String getDownloadUrl() {return downloadUrl;
}

public void setDownloadUrl(String downloadUrl) {this.downloadUrl = downloadUrl;
}

}

8、网络监测

 * 网络检查* @author 00**/
public class NetworkUtil {
/**
* 没有网络*/public static final int NONETWORK = 0;

/**
* 当前是wifi连接*/public static final int WIFI = 1;

/**
* 不是wifi连接*/public static final int NOWIFI = 2;

/**
* 检测当前网络的类型 是否是wifi* @param context* @return*/public static int checkedNetWorkType(Context context){if(!checkedNetWork(context)){ return NONETWORK;
}

ConnectivityManager cm
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting() ){ return WIFI;
}
else{ return NOWIFI;
}

}


/**
* 检查是否连接网络* @param context* @return*/public static booleancheckedNetWork(Context context){
//
1.获得连接设备管理器ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm == null) return false;

/**
* 获取网络连接对象*/NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if(networkInfo == null || !networkInfo.isAvailable()){ return false;
}

return true;
}

}

9、json解析类


/**
* json 和 实体类之间的相互转换* @author 00**/public class JsonUtil {
/**
* 将一个实体对象转换成一个json字符串提示对象中可包含集合* @param t 实体类* @return*/public static <T> String beanToJson(T t){Gson gson = new Gson();
String json
= gson.toJson(t);
return json;
}


/**
* 将一个json字符串 转换成一个实体类对象 可包含list* @param json* @param t* @return*/public static <T>
T jsonToBean(String json,Class<T>
class1) throws InstantiationException, IllegalAccessException{Gson gson = new Gson();
T t
= class1.newInstance();
t
=gson.fromJson(json, class1);
return t;
}


/**
* 将json字符串转换成一个json对象* @param str* @return*/public static JSONObject stringToJson(String str){try { return new JSONObject(str);
}

catch (JSONException e) { e.printStackTrace();
return null;
}

}

public static String getString(InputStream is){try { ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while((len = is.read(buffer)) != -1){baos.write(buffer, 0, len);
}

byte[] byteArray = baos.toByteArray();

//
String str = new String(byteArray);
return new String(byteArray,"utf-8");
}

catch (IOException e) { e.printStackTrace();
}

return "";
}


/**
* 从assert文件夹中读取json文件,然后转化为json对象* @throws Exception*/public static JSONObject getJsonDataFromAssets(Context context,String jsonFileName) throws Exception{JSONObject mJsonObj = null;
StringBuffer sb
= new StringBuffer();
InputStream is
= context.getAssets().open(jsonFileName);
int len = -1;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1){ sb.append(new String(buf, 0, len, "UTF-8"));
}

is.close();
mJsonObj
= new JSONObject(sb.toString());
return mJsonObj;
}

}

10、http请求类


/**
* http请求工具类* @author winfo-wj**/public class HttpRequest { private static HttpUtils http = new HttpUtils();

/**
* 请求回调接口* @author winfo-wj**/public interface RequestCallBackListener{
/**
* 请求成功* @param resultData服务器返回的结果数据*/public void onSuccess(String resultData);

/**
* 请求失败* @param error 错误信息*/public void onFailure(String error);
}


/**
* get请求* @param url 请求路径* @param requestCallBackListener 请求回调*/public static void get(String url , final RequestCallBackListener requestCallBackListener){http.configTimeout(1000*10);
http.send(HttpMethod.GET, url,
new RequestCallBack<String>() {@Override public void onSuccess(ResponseInfo<String> response) {requestCallBackListener.onSuccess(response.result);

猜你喜欢
git分布式版本控制玩法 RabbitMQ 一二事(5) - 通配符模式应用
开发资源小结~持续更新中 查看Linux系统版本信息
CSS弹性盒模型flex在布局中的应用 Java 基础入门随笔(11) JavaSE版——继承
Swift之语法2(精简版) 简单的计算功能
用gulp做一个略完整的前端打包工作 精仿百思不得姐客户端应用iOS源码