android版本更新功能-完整版
Posted 渐行渐远丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android版本更新功能-完整版相关的知识,希望对你有一定的参考价值。
github地址:https://github.com/wj576038874/DownloadUpdate
使用retrfit2 rxjava2 okhttp3实现多文件多线程下载(支持断点下载), android版本更新:通知栏更新,对话框更新 兼容8.0
此博客中的内容是比较老的版本了,可以不用看了,可以直接下载githubhttps://github.com/wj576038874/DownloadUpdate上的最新版本,通知栏更新显示下载进度并且兼容8.0,支持多文件多线程断点下载
github上的版本效果图:
1、检测是否有新版本
<pre class="java" name="code">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() {
@Override
public void onClick(View v) {
//本地测试检测是否有新版本发布
UpdateVersionUtil.localCheckedVersion(MainActivity.this,new UpdateListener() {
@Override
public 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() {
@Override
public 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、版本检测的工具类
<pre class="java" name="code">/**
*
* @author wenjie
* 版本更新的工具类
*/
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() {
@Override
public 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、增加xxxxx功能\\n2、增加xxxx显示!\\n3、用户界面优化!\\n4、xxxxxx!");
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() {
@Override
public 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() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
/**
* 收起通知栏
* @param context
*/
public static void collapsingNotification(Context context) {
Object service = context.getSystemService("statusbar");
if (null == service)
return;
try {
Class<?> clazz = Class.forName("android.app.StatusBarManager");
int sdkVersion = android.os.Build.VERSION.SDK_INT;
Method collapse;
if (sdkVersion <= 16) {
collapse = clazz.getMethod("collapse");
} else {
collapse = clazz.getMethod("collapsePanels");
}
collapse.setAccessible(true);
collapse.invoke(service);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、版本检测的状态类
<pre class="java" name="code">/**
*
* @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 android7.0上 通知栏不兼容,可以用后面一个service,通知栏兼容7.0的,下载下来的demo直接替换掉这个类即可
<pre class="java" name="code">/**
*
* @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;//文件的总长度
@Override
public 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>() {
@Override
public 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.collapsingNotification(UpdateService.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, "智慧海事");
// 更改文字
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, "正在下载:智慧海事");
// 更改文字
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;
}
}
兼容7.0的
/**
*
* @author wenjie
* 下载新版本的服务类
*/
public class UpdateVersionService extends Service {
private NotificationManager nm;
private NotificationCompat.Builder builder;
private Notification notification;
//标题标识
private int titleId = 0;
//安装文件
private File updateFile;
private HttpUtils httpUtils;
private long initTotal = 0;//文件的总长度
@Override
public void onCreate() {
super.onCreate();
httpUtils = new HttpUtils();
updateFile = new File(SDCardUtils.getRootDirectory() + "/updateVersion/gdmsaec-app.apk");
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
builder = new NotificationCompat.Builder(getApplicationContext());
notification = builder
.setContentTitle("正在下载:智慧海事")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setOngoing(true)
.build();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(updateFile.exists()){
updateFile.delete();
}
Bundle bundle = intent.getExtras();
String url = bundle.getString("downloadUrl");
nm.notify(titleId, notification);
downLoadFile(url);
startForeground(titleId, notification);
return super.onStartCommand(intent, flags, startId);
}
public void downLoadFile(String url){
httpUtils.download(url,updateFile.getAbsolutePath(), true, false, new RequestCallBack<File>() {
@Override
public void onSuccess(ResponseInfo<File> response) {
// 发送消息
notification = builder
.setContentTitle("下载完成!点击安装")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.build();
nm.notify(0, notification);
UpdateVersionUtil.collapsingNotification(UpdateVersionService.this);
stopSelf();
//自动安装新版本
Intent installIntent = ApkUtils.getInstallIntent(updateFile);
startActivity(installIntent);
nm.cancel(titleId);
}
@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, "智慧海事");
// // 更改文字
// 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);
stopSelf();
nm.cancel(titleId);
ToastUtils.showToast(getApplicationContext() , "下载失败,请检查网络!");
}
@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, "正在下载:智慧海事");
// // 更改文字
// notification.contentView.setTextViewText(R.id.bartext, l+ "%");
// // 更改进度条
// notification.contentView.setProgressBar(R.id.progressBar1, 100,(int)l, false);
// 发送消息
notification = builder
.setContentTitle("正在下载:智慧海事")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText((int)l+"%")
.setProgress(100,(int)l, false)
.setOngoing(true)
.build();
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 = builder
.setContentTitle("开始下载:智慧海事")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setOngoing(true)
.build();
nm.notify(titleId, notification);
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<pre class="java" name="code">/**
* Toast工具箱 可防止用户多次点击之后 显示消息的时长太长
*/
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根目录
* 获取SD卡的状态
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 String versionName;//版本名
private int versionCode;//版本号
private String versionDesc;//版本描述信息内容
private String downloadUrl;//新版本的下载路径
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、网络监测
<pre class="java" name="code">/**
* 网络检查
* @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 boolean checkedNetWork(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解析类
<pre class="java" name="code">/**
* 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请求类
<pre class="java" name="code">/**
* 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);
}
@Override
public void onFailure(HttpException error, String msg) {
requestCallBackListener.onFailure(msg);
}
});
}
/**
* post请求
* @param url 请求地址
* @param params 请求参数
* @param requestCallBackListener 请求回调
*/
public static void post(String url ,RequestParams params , final RequestCallBackListener requestCallBackListener){
http.configTimeout(1000*10);
http.send(HttpMethod.POST, url, params, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> response) {
requestCallBackListener.onSuccess(response.result);
}
@Override
public void onFailure(HttpException error, String msg) {
requestCallBackListener.onFailure(msg);
}
});
}
}
12、通知栏的布局
<pre class="html" name="code"><pre class="html" name="code"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_vertical"
>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/ic_launcher"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="3"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_gravity="center_vertical"
>
<TextView
android:id="@+id/msg"
android:text="正在下载:xxx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="14sp"
/>
<TextView
android:id="@+id/bartext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0%"
android:textColor="#ffffff"
android:textSize="12sp"
/>
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp" />
<!--
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/btnStartStop"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="25dp"
android:text="暂停"
android:textSize="12sp"
android:textColor="#ffffff"
/>
<Button
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="25dp"
android:text="取消"
android:textSize="12sp"
android:textColor="#ffffff"
/>
</LinearLayout>
-->
</LinearLayout>
</LinearLayout>
</LinearLayout>
14、按本更新提示的对话框布局文件
<pre class="html" name="code"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_centerInParent="true"
android:layout_marginRight="60dp"
android:background="@drawable/dialog_bg"
android:orientation="vertical" >
<!-- Title -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="45dp" >
<ImageView
android:id="@+id/umeng_wifi_indicator"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:src="@drawable/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="发现新版本"
android:textSize="@dimen/normal_text_size"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/black" />
</RelativeLayout>
<!-- split -->
<View
android:layout_width="fill_parent"
android:layout_height="0.5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#d8d8d8" />
<!-- Content -->
<ScrollView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:padding="10dp"
android:layout_weight="1" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_update_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="最新版本:xxxv2.2.1"
android:textColor="@color/black"
android:textSize="@dimen/medium_text_size"
/>
<TextView
android:id="@+id/tv_update_msg_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="新版本大小:19.07M"
android:textSize="@dimen/medium_text_size"
android:layout_marginTop="10dp"
android:textColor="@color/black"
/>
<TextView
android:id="@+id/tv_update_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="60dp"
android:textSize="@dimen/medium_text_size"
android:lineSpacingExtra="3dp"
android:textColor="@color/black"
/>
</LinearLayout>
</ScrollView>
<!-- Ignore CheckBox -->
<!-- OK&Cancel Button -->
<LinearLayout
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btn_update_id_cancel"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="@drawable/dialog_cancel_btn_bg"
android:text="以后再说"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="10dp"
android:textSize="@dimen/normal_text_size"
android:textColor="@color/black" />
<Button
android:id="@+id/btn_update_id_ok"
android:layout_width="0dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_height="40dp"
android:layout_weight="1"
android:textSize="@dimen/normal_text_size"
android:background="@drawable/dialog_ok_btn_bg"
android:text="立即更新"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
15、对话框按钮的.9图
16、字体颜色
<!-- 黑色 -->
<color name="black">#333333</color>
17、字体大小文件
<dimen name="title_text_size">18sp</dimen><!-- 标题字体大小 -->
<dimen name="normal_text_size">16sp</dimen><!-- 通常字体大小 -->
<dimen name="medium_text_size">14sp</dimen><!-- 中等字体大小 -->
<dimen name="small_text_size">12sp</dimen><!-- 小号字体大小 -->
以上是关于android版本更新功能-完整版的主要内容,如果未能解决你的问题,请参考以下文章
教你如何使用android studio发布release 版本(完整版)