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;
	}

}




5、吐司的工具类
<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 版本(完整版)

QT5软件开发入门教程(完整版-持续更新)

QT5软件开发入门教程(完整版-持续更新)

使用Android studio制作一个APP?完整版教学

在 Codename One 中管理我的应用程序的演示/完整版

中国移动短信网关错误代码汇总(完整版)