码迷,mamicode.com
首页 > 移动开发 > 详细

android版本更新功能-完整版

时间:2016-05-20 14:36:55      阅读:316      评论:0      收藏:0      [点我收藏+]

标签:

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

1、检测是否有新版本

<pre class="java" name="code">//访问服务器是否有新版本发布
		UpdateVersionUtil.checkVersion(MainActivity.this);
		//设置版本更新的回调接口
		UpdateVersionUtil.setUpdateListener(new UpdateListener() {
			@Override
			public void onUpdateReturned(int updateStatus,final 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">import java.io.File;
import java.lang.reflect.Method;
import org.json.JSONArray;
import org.json.JSONObject;
import com.example.updateversion.HttpRequest.RequestCallBackListener;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

/**
 * 
 * @author	wenjie
 *	版本更新的工具类
 */
public class UpdateVersionUtil{
	
	/**
	 * 接口回调
	 * @author wenjie
	 *
	 */
	public interface UpdateListener{
		void onUpdateReturned(int updateStatus,VersionInfo versionInfo);
	}
	
	public static UpdateListener updateListener;
	
	public static void setUpdateListener(UpdateListener updateListener) {
		UpdateVersionUtil.updateListener = updateListener;
	}
	
	/**
	 * 检测版本
	 * @param context 上下文
	 */
	public static void checkVersion(final Context context){
		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);
			}
		});
	}
	
	/**
	 * 弹出新版本提示
	 * @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 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、版本更新的实体类

<pre class="java" name="code">import java.io.Serializable;

/**
 * @项目名: 	gdmsaec-app
 * @包名:	com.winfo.gdmsaec.app.domain
 * @类名:	VersionInfo
 * @创建者:	wenjie
 * @创建时间:	2015-10-14	上午11:06:08 
 * @描述:	app版本信息封装类
 * 
 * @svn版本:	$Rev: 1304 $
 * @更新人:	$Author: wenjie $
 * @更新时间:	$Date: 2016-02-27 14:58:42 +0800 (Sat, 27 Feb 2016) $
 * @更新描述:	TODO
 */
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;
	}
	
}



 

4、版本更新的状态类

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



 

5、版本更新的服务

<pre class="java" name="code">import java.io.File;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.RemoteViews;

/**
 * 
 * @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.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, "智慧海事");
	                // 更改文字
	                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;
	}
	
	
}



 

6、操作APK文件的工具类

<pre class="java" name="code">import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.AsyncTask;

/**
 * 
 * @项目名: 	gdmsaec-app
 * @包名:	com.winfo.gdmsaec.app.utils
 * @类名:	ApkUtils
 * @创建者:	yanfeijun
 * @创建时间:	2015-10-14	上午10:57:36 
 * @描述:	获取app相关信息的工具类
 * 
 * @svn版本:	$Rev: 1161 $
 * @更新人:	$Author: wenjie $
 * @更新时间:	$Date: 2016-01-25 14:21:41 +0800 (Mon, 25 Jan 2016) $
 * @更新描述:	TODO
 */
public class ApkUtils {
	private static final String TAG = ApkUtils.class.getSimpleName();

	/**
	 * 获取应用程序名称
	 */
	public static String getAppName(Context context) {
		try {
			PackageManager packageManager = context.getPackageManager();
			PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
			int labelRes = packageInfo.applicationInfo.labelRes;
			return context.getResources().getString(labelRes);
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取应用程序版本名称信息
	 * 
	 * @param context
	 * @return 当前应用的版本名称
	 */
	public static String getVersionName(Context context) {
		try {
			PackageManager packageManager = context.getPackageManager();
			PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
			return packageInfo.versionName;

		} catch (NameNotFoundException e) {

		}
		return null;
	}

	/**
	 * @return 当前程序的版本号
	 */
	public static int getVersionCode(Context context) {
		int version;
		try {
			PackageManager pm = context.getPackageManager();
			PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
			version = packageInfo.versionCode;
		} catch (Exception e) {
			e.printStackTrace();
			version = 0;
		}
		return version;
	}

	/**
	 * 得到安装的intent
	 * @param apkFile
	 * @return
	 */
	public static Intent getInstallIntent(File apkFile) {
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_VIEW);
		intent.setDataAndType(Uri.fromFile(new File(apkFile.getAbsolutePath())),
				"application/vnd.android.package-archive");
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		return intent;
	}
	

}



 

7、网络访问的请求工具类

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;

/**
 * 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);
			}
		});
	}
}



 

8、jaon解析工具类

<pre class="java" name="code">import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;

import com.google.gson.Gson;

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



 

9、网络状态监听的工具类

<pre class="java" name="code">import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

/**
 * 网络检查
 * @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;
	}
}



 

10、临时文件保存

<pre class="java" name="code">import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.exception.DbException;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
 * 
 * @项目名: 	WinfoSeaMap
 * @包名:	com.winfo.seamap.utils
 * @类名:	PreferenceUtils
 * @创建者:	yanfeijun
 * @创建时间:	2015-9-15	上午10:55:24 
 * @描述:	SharedPreferences工具类
 * 
 * @svn版本:	$Rev: 93 $
 * @更新人:	$Author: wenjie $
 * @更新时间:	$Date: 2015-09-24 15:48:12 +0800 (Thu, 24 Sep 2015) $
 * @更新描述:	TODO
 */
public class PreferenceUtils
{
	private static SharedPreferences	mSp;
	private final static String			SP_NAME	= "config";

	/**
	 * 获得sharePreference内存对象
	 * 
	 * @param context
	 * @return
	 */
	private static SharedPreferences getSp(Context context)
	{
		if (mSp == null)
		{
			mSp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
		}
		return mSp;
	}

	/**
	 * 获取boolean类型的值
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @param defValue
	 *            如果没有对应的值,
	 * @return
	 */
	public static boolean getBoolean(Context context, String key, boolean defValue)
	{
		SharedPreferences sp = getSp(context);
		return sp.getBoolean(key, defValue);
	}

	/**
	 * 获取boolean类型的值,如果没有对应的值,默认值返回false
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @return
	 */
	public static boolean getBoolean(Context context, String key)
	{
		return getBoolean(context, key, false);
	}

	
	/**
	 * 设置int类型的值
	 * 
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void setInt(Context context, String key, int value)
	{
		SharedPreferences sp = getSp(context);
		Editor editor = sp.edit();
		editor.putInt(key, value);
		editor.commit();
	}
	
	
	
	/**
	 * 设置boolean类型的值
	 * 
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void setBoolean(Context context, String key, boolean value)
	{
		SharedPreferences sp = getSp(context);
		Editor editor = sp.edit();
		editor.putBoolean(key, value);
		editor.commit();
	}

	/**
	 * 获取String类型的值
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @param defValue
	 *            如果没有对应的值,
	 * @return
	 */
	public static String getString(Context context, String key, String defValue)
	{
		SharedPreferences sp = getSp(context);
		return sp.getString(key, defValue);
	}

	/**
	 * 获取int类型的值
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @param defValue
	 *            如果没有对应的值,
	 * @return
	 */
	public static int getInt(Context context, String key, int defValue)
	{
		SharedPreferences sp = getSp(context);
		return sp.getInt(key, defValue);
	}
	
	/**
	 * 获取String类型的值,如果没有对应的值,默认值返回null
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @return
	 */
	public static String getString(Context context, String key)
	{
		return getString(context, key, null);
	}

	/**
	 * 设置String类型的值
	 * 
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void setString(Context context, String key, String value)
	{
		SharedPreferences sp = getSp(context);
		Editor editor = sp.edit();
		editor.putString(key, value);
		editor.commit();
	}

	/**
	 * 获取long类型的值
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @param defValue
	 *            如果没有对应的值,
	 * @return
	 */
	public static long getLong(Context context, String key, long defValue)
	{
		SharedPreferences sp = getSp(context);
		return sp.getLong(key, defValue);
	}

	/**
	 * 获取long类型的值,如果没有对应的值,默认值返回0
	 * 
	 * @param context
	 *            上下文
	 * @param key
	 *            对应的键
	 * @return
	 */
	public static Long getLong(Context context, String key)
	{
		return getLong(context, key, 0);
	}

	/**
	 * 设置Long类型的值
	 * 
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void setLong(Context context, String key, long value)
	{
		SharedPreferences sp = getSp(context);
		Editor editor = sp.edit();
		editor.putLong(key, value);
		editor.commit();
	}
	
	/**
	 * 根据key值删除指定的数据
	 * @param context
	 * @param key
	 */
	public static void remove(Context context , String key){
		SharedPreferences sp = getSp(context);
		Editor editor = sp.edit();
		editor.remove(key);
		editor.commit();
	}
}



 

11、sdcard操作工具类

<pre class="java" name="code">import java.io.File;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;

/**
 * 
 * @项目名: 	gdmsaec-app
 * @包名:	com.winfo.gdmsaec.app.utils
 * @类名:	SDCardUtils
 * @创建者:	yanfeijun
 * @创建时间:	2015-10-20	下午3:38:10 
 * @描述:	SD卡工具类
 * 
 * @svn版本:	$Rev$
 * @更新人:	$Author$
 * @更新时间:	$Date$
 * @更新描述:	TODO
 */
public class SDCardUtils {
	
	public static String getPath(){
		return Environment.getExternalStorageDirectory().getAbsolutePath();
	} 
	/**
	 * 获取SD卡的状态
	 * @return
	 */
	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;
	}

	/**
	 * 获取SD卡的根路径
	 * @return null:不存在SD卡
	 */
	public static String getRootPath(){
		File rootDirectory = getRootDirectory();
		return rootDirectory != null ?rootDirectory.getPath():null;
	}

	/**
	 * 获取SD卡总的容量
	 * @return 总容量;-1:SD卡不可用
	 */
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
	public static long getTotalSize(){
		if(isAvailable()){
			StatFs statFs = new StatFs(getRootDirectory().getPath());
			if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){
				return statFs.getBlockCount() * statFs.getBlockSize();
			}else{
				return statFs.getBlockCount() * statFs.getBlockSize();
			}
		}else{
			return -1;
		}
	}

	/**
	 * 获取SD卡中可用的容量
	 * @return 可用的容量;-1:SD卡不可用
	 */
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
	public static long getAvailableSize(){
		if(isAvailable()){
			StatFs statFs = new StatFs(getRootDirectory().getPath());
			if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){
				return statFs.getAvailableBlocks() * statFs.getBlockSize();
			}else{
				return statFs.getAvailableBlocks() * statFs.getBlockSize();
			}
		}else{
			return -1;
		}
	}
}


12、吐司工具类

<pre class="java" name="code">import android.content.Context;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Toast工具箱  可防止用户多次点击之后 显示消息的时长太长  利用handler消息机制
 */
public class ToastUtils {
	
	private static String oldMsg;  
    protected static Toast toast   = null;  
    private static long oneTime=0;  
    private static long twoTime=0;  
    private static Handler handler = new Handler();
    private static Runnable runnable = new Runnable() {
		@Override
		public void run() {
			toast.cancel();
			toast = null;
		}
	};
    /**
     * 吐出一个显示时间较短的提示
     * @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;  
    }
    
    
    
    


	/**
	 * 吐出一个显示时间较短的提示
	 * @param context 上下文对象
	 * @param resId 显示内容资源ID
	 */
	public static final void showToast(Context context, int resId){
		showToast(context, context.getString(resId));
	}

	
	/**
	 * 吐出一个显示时间较长的提示
	 * @param context 上下文对象
	 * @param formatResId 被格式化的字符串资源的ID
	 * @param args 参数数组
	 */
	public static final void toastL(Context context, int formatResId, Object... args){
		Toast.makeText(context, String.format(context.getString(formatResId), args), Toast.LENGTH_LONG).show();
	}

	/**
	 * 吐出一个显示时间较短的提示
	 * @param context 上下文对象
	 * @param formatResId 被格式化的字符串资源的ID
	 * @param args 参数数组
	 */
	public static final void toastS(Context context, int formatResId, Object... args){
		Toast.makeText(context, String.format(context.getString(formatResId), args), Toast.LENGTH_SHORT).show();
	}

	/**
	 * 吐出一个显示时间较长的提示
	 * @param context 上下文对象
	 * @param format 被格式化的字符串
	 * @param args 参数数组
	 */
	public static final void toastL(Context context, String format, Object... args){
		Toast.makeText(context, String.format(format, args), Toast.LENGTH_LONG).show();
	}

	/**
	 * 吐出一个显示时间较短的提示
	 * @param context 上下文对象
	 * @param format 被格式化的字符串
	 * @param args 参数数组
	 */
	public static final void toastS(Context context, String format, Object... args){
		Toast.makeText(context, String.format(format, args), Toast.LENGTH_SHORT).show();
	}

}



13、通知栏的布局

<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="正在下载:智慧海事"
	            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="最新版本:智慧海事v2.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:text="\n更新内容:\n1、处理了海图上长按定点查询附近通航要素和船舶的bug\n2、新增点击消息列表查看消息类容\n3、调整经纬度变化距离获取消息通知,以及优化消息列表的显示样式\n4、海图切换窗口里面新增 显示当前屏幕范围内的AIS数据\n"
                    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版本更新功能-完整版

标签:

原文地址:http://blog.csdn.net/csdn576038874/article/details/51460180

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!