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

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

1、检测是否有新版本

public class MainActivity extends Activity {private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = (Button) findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//本地测试检测是否有新版本发布UpdateVersionUtil.localCheckedVersion(MainActivity.this,new UpdateListener() {@Overridepublic void onUpdateReturned(int updateStatus, VersionInfo versionInfo) {//判断回调过来的版本检测状态switch (updateStatus) {case UpdateStatus.YES://弹出更新提示UpdateVersionUtil.showDialog(MainActivity.this,versionInfo);break;case UpdateStatus.NO://没有新版本ToastUtils.showToast(getApplicationContext(), "已经是最新版本了!");break;case UpdateStatus.NOWIFI://当前是非wifi网络ToastUtils.showToast(getApplicationContext(), "只有在wifi下更新!");
//                            DialogUtils.showDialog(MainActivity.this, "温馨提示","当前非wifi网络,下载会消耗手机流量!", "确定", "取消",new DialogOnClickListenner() {
//                                @Override
//                                public void btnConfirmClick(Dialog dialog) {
//                                    dialog.dismiss();
//                                    //点击确定之后弹出更新对话框
//                                    UpdateVersionUtil.showDialog(SystemActivity.this,versionInfo);
//                                }
//
//                                @Override
//                                public void btnCancelClick(Dialog dialog) {
//                                    dialog.dismiss();
//                                }
//                            });break;case UpdateStatus.ERROR://检测失败ToastUtils.showToast(getApplicationContext(), "检测失败,请稍后重试!");break;case UpdateStatus.TIMEOUT://链接超时ToastUtils.showToast(getApplicationContext(), "链接超时,请检查网络设置!");break;}}});/*** //访问服务器 试检测是否有新版本发布UpdateVersionUtil.localCheckedVersion(MainActivity.this,new UpdateListener() {@Overridepublic void onUpdateReturned(int updateStatus, VersionInfo versionInfo) {//判断回调过来的版本检测状态switch (updateStatus) {case UpdateStatus.YES://弹出更新提示UpdateVersionUtil.showDialog(MainActivity.this,versionInfo);break;case UpdateStatus.NO://没有新版本ToastUtils.showToast(getApplicationContext(), "已经是最新版本了!");break;case UpdateStatus.NOWIFI://当前是非wifi网络ToastUtils.showToast(getApplicationContext(), "只有在wifi下更新!");
//                            DialogUtils.showDialog(MainActivity.this, "温馨提示","当前非wifi网络,下载会消耗手机流量!", "确定", "取消",new DialogOnClickListenner() {
//                                @Override
//                                public void btnConfirmClick(Dialog dialog) {
//                                    dialog.dismiss();
//                                    //点击确定之后弹出更新对话框
//                                    UpdateVersionUtil.showDialog(SystemActivity.this,versionInfo);
//                                }
//
//                                @Override
//                                public void btnCancelClick(Dialog dialog) {
//                                    dialog.dismiss();
//                                }
//                            });break;case UpdateStatus.ERROR://检测失败ToastUtils.showToast(getApplicationContext(), "检测失败,请稍后重试!");break;case UpdateStatus.TIMEOUT://链接超时ToastUtils.showToast(getApplicationContext(), "链接超时,请检查网络设置!");break;}}});*/}});}
}

2、版本检测的工具类

/*** * @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() {@Overridepublic void onSuccess(String resultData) {try {JSONObject jsonObject = JsonUtil.stringToJson(resultData);JSONArray array = jsonObject.getJSONArray("data");VersionInfo mVersionInfo = JsonUtil.jsonToBean(array.getJSONObject(0).toString(), VersionInfo.class);int clientVersionCode = ApkUtils.getVersionCode(context);int serverVersionCode = mVersionInfo.getVersionCode();//有新版本if(clientVersionCode < serverVersionCode){int i = NetworkUtil.checkedNetWorkType(context);if(i == NetworkUtil.NOWIFI){updateListener.onUpdateReturned(UpdateStatus.NOWIFI,mVersionInfo);}else if(i == NetworkUtil.WIFI){updateListener.onUpdateReturned(UpdateStatus.YES,mVersionInfo);}}else{//无新本updateListener.onUpdateReturned(UpdateStatus.NO,null);}} catch (Exception e) {e.printStackTrace();updateListener.onUpdateReturned(UpdateStatus.ERROR,null);}}@Overridepublic void onFailure(String error) {updateListener.onUpdateReturned(UpdateStatus.TIMEOUT,null);}});}/*** 本地测试*/public static void localCheckedVersion(final Context context,final UpdateListener updateListener){try {
//            JSONObject jsonObject = JsonUtil.stringToJson(resultData);
//            JSONArray array = jsonObject.getJSONArray("data");
//            VersionInfo mVersionInfo = JsonUtil.jsonToBean(array.getJSONObject(0).toString(), VersionInfo.class);VersionInfo mVersionInfo = new VersionInfo();mVersionInfo.setDownloadUrl("http://gdown.baidu.com/data/wisegame/57a788487345e938/QQ_358.apk");mVersionInfo.setVersionDesc("\n更新内容:\n1、增加xxxxxxxxx功能\n2、增加xxxxxxxxx显示!\n3、用户界面优化!\n4、处理了xxxxxxxxBUG!");mVersionInfo.setVersionCode(2);mVersionInfo.setVersionName("v2020");mVersionInfo.setVersionSize("20.1M");mVersionInfo.setId("1");int clientVersionCode = ApkUtils.getVersionCode(context);int serverVersionCode = mVersionInfo.getVersionCode();//有新版本if(clientVersionCode < serverVersionCode){int i = NetworkUtil.checkedNetWorkType(context);if(i == NetworkUtil.NOWIFI){updateListener.onUpdateReturned(UpdateStatus.NOWIFI,mVersionInfo);}else if(i == NetworkUtil.WIFI){updateListener.onUpdateReturned(UpdateStatus.YES,mVersionInfo);}}else{//无新本updateListener.onUpdateReturned(UpdateStatus.NO,null);}} catch (Exception e) {e.printStackTrace();updateListener.onUpdateReturned(UpdateStatus.ERROR,null);}}/*** 弹出新版本提示* @param context 上下文* @param versionInfo 更新内容*/public static void showDialog(final Context context,final VersionInfo versionInfo){final Dialog dialog = new AlertDialog.Builder(context).create();final File file = new File(SDCardUtils.getRootDirectory()+"/updateVersion/gdmsaec-app.apk");dialog.setCancelable(true);// 可以用“返回键”取消  dialog.setCanceledOnTouchOutside(false);//
        dialog.show();View view = LayoutInflater.from(context).inflate(R.layout.version_update_dialog, null);dialog.setContentView(view);final Button btnOk = (Button) view.findViewById(R.id.btn_update_id_ok);Button btnCancel = (Button) view.findViewById(R.id.btn_update_id_cancel);TextView tvContent = (TextView) view.findViewById(R.id.tv_update_content);TextView tvUpdateTile = (TextView) view.findViewById(R.id.tv_update_title);final TextView tvUpdateMsgSize = (TextView) view.findViewById(R.id.tv_update_msg_size);tvContent.setText(versionInfo.getVersionDesc());tvUpdateTile.setText("最新版本:"+versionInfo.getVersionName());if(file.exists() && file.getName().equals("gdmsaec-app.apk")){tvUpdateMsgSize.setText("新版本已经下载,是否安装?");}else{tvUpdateMsgSize.setText("新版本大小:"+versionInfo.getVersionSize());}btnOk.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {dialog.dismiss();if(v.getId() == R.id.btn_update_id_ok){//新版本已经下载if(file.exists() && file.getName().equals("gdmsaec-app.apk")){Intent intent = ApkUtils.getInstallIntent(file);context.startActivity(intent);}else{//没有下载,则开启服务下载新版本Intent intent = new Intent(context,UpdateVersionService.class);intent.putExtra("downloadUrl", versionInfo.getDownloadUrl());context.startService(intent);}}}});btnCancel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {dialog.dismiss();}});}/*** 收起通知栏* @param context*/public static void collapseStatusBar(Context context) { try{Object statusBarManager = context.getSystemService("statusbar"); Method collapse;if (Build.VERSION.SDK_INT <= 16){collapse = statusBarManager.getClass().getMethod("collapse"); }else{ collapse = statusBarManager.getClass().getMethod("collapsePanels"); } collapse.invoke(statusBarManager);}catch (Exception localException){ localException.printStackTrace();} }
}

3、版本检测的状态类

/*** * @author wenjie*    检测版本的状态类*/
public interface UpdateStatus {/*** 没有新版本*/public static int NO = 1;/*** 有新版本*/public static int YES = 2;/*** 链接超时*/public static int TIMEOUT = 3;/*** 没有wifi*/public static int NOWIFI = 4;/*** 数据解析出错*/public static int ERROR = -1;
}

4、版本更新的service

/*** * @author wenjie*    下载新版本的服务类*/
public class UpdateVersionService extends Service {private NotificationManager nm;private Notification notification;//标题标识private int titleId = 0;//安装文件private File updateFile;private static HttpHandler<File> httpHandler;private HttpUtils httpUtils;private long initTotal = 0;//文件的总长度
    @Overridepublic void onCreate() {super.onCreate();httpUtils = new HttpUtils();updateFile = new File(SDCardUtils.getRootDirectory()+"/updateVersion/gdmsaec-app.apk");nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notification = new Notification();notification.icon = R.drawable.ic_launcher;notification.tickerText = "开始下载";notification.when = System.currentTimeMillis();notification.contentView = new RemoteViews(getPackageName(), R.layout.notifycation);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//        VersionInfo versionInfo = (VersionInfo) intent.getSerializableExtra("versionInfo");
//        String url = versionInfo.getDownloadUrl();Bundle bundle = intent.getExtras();String url = bundle.getString("downloadUrl");PreferenceUtils.setString(UpdateVersionService.this, "apkDownloadurl", url);nm.notify(titleId, notification);downLoadFile(url);return super.onStartCommand(intent, flags, startId);}public void downLoadFile(String url){httpHandler = httpUtils.download(url,updateFile.getAbsolutePath(), true, false, new RequestCallBack<File>() {@Overridepublic void onSuccess(ResponseInfo<File> response) {// 更改文字notification.contentView.setTextViewText(R.id.msg, "下载完成!点击安装");
//                notification.contentView.setViewVisibility(R.id.btnStartStop, View.GONE);
//                notification.contentView.setViewVisibility(R.id.btnCancel,View.GONE);// 发送消息nm.notify(0, notification);stopSelf();//收起通知栏UpdateVersionUtil.collapseStatusBar(UpdateVersionService.this);//自动安装新版本Intent installIntent = ApkUtils.getInstallIntent(updateFile);startActivity(installIntent);}@Overridepublic void onFailure(HttpException error, String msg) {//网络连接错误if(error.getExceptionCode() == 0 ){// 更改文字notification.contentView.setTextViewText(R.id.msg, "网络异常!请检查网络设置!");}else if(error.getExceptionCode() == 416){//文件已经下载完毕// 更改文字notification.contentView.setTextViewText(R.id.msg, "xxx");// 更改文字notification.contentView.setTextViewText(R.id.bartext, "检测到新版本已经下载完成,点击即安装!");// 隐藏进度条
                    notification.contentView.setViewVisibility(R.id.progressBar1, View.GONE);Intent intent = ApkUtils.getInstallIntent(updateFile);PendingIntent pendingIntent = PendingIntent.getActivity(UpdateVersionService.this, 0, intent, 0);notification.flags = Notification.FLAG_AUTO_CANCEL;//点击通知栏之后 消失notification.contentIntent  = pendingIntent;//启动指定意图
                }// 发送消息nm.notify(0, notification);}@Overridepublic void onLoading(long total, long current, boolean isUploading) {if(initTotal == 0){//说明第一次开始下载initTotal = total;}if(initTotal != total){//说明下载过程中暂停过,文件的总长度出现问题  就把初始的文件的长度赋值给他重新计算已经下载的比例total = initTotal;}long l = current*100/total;notification.contentView.setTextViewText(R.id.msg, "正在下载:xxx");// 更改文字notification.contentView.setTextViewText(R.id.bartext, l+ "%");// 更改进度条notification.contentView.setProgressBar(R.id.progressBar1, 100,(int)l, false);// 发送消息nm.notify(0, notification);//              Intent intent = new Intent();
//                intent.setAction("cancel");
//                PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
//                notification.contentView.setOnClickPendingIntent(R.id.btnStartStop, pendingIntent);
                }@Overridepublic void onStart() {notification.contentView.setTextViewText(R.id.msg, "开始下载:智慧海事");nm.notify(titleId, notification);}});}public static HttpHandler<File> getHandler(){return httpHandler;}@Overridepublic void onDestroy() {//下载完成时,清楚该通知,自动安装
        nm.cancel(titleId);System.out.println("UpdateVersionService----onDestroy");
//        try {
//            GdmsaecApplication.db.deleteAll(VersionInfo.class);
//        } catch (DbException e) {
//            e.printStackTrace();
//        }super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {return null;}
}

5、吐司的工具类

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

6、获取sdcard根目录

public static String getState(){  return Environment.getExternalStorageState();
}  /** * SD卡是否可用 * @return 只有当SD卡已经安装并且准备好了才返回true */
public static boolean isAvailable(){  return getState().equals(Environment.MEDIA_MOUNTED);
}  /** * 获取SD卡的根目录 * @return null:不存在SD卡 */
public static File getRootDirectory(){  return isAvailable()?Environment.getExternalStorageDirectory():null;
}  

7、版本检测的实体类

public class VersionInfo implements Serializable{  /** *  */  private static final long serialVersionUID = 1L;  private String id;  private 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、网络监测

 * 网络检查 * @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解析类

/** * json 和 实体类之间的相互转换 * @author 00 * */
public class JsonUtil {  /** * 将一个实体对象  转换成一个json字符串  提示对象中可包含集合 * @param t 实体类 * @return */  public static <T> String beanToJson(T t){  Gson gson = new Gson();  String json = gson.toJson(t);  return json;  }  /** * 将一个json字符串 转换成一个实体类对象 可包含list * @param json * @param t * @return */  public static <T> T jsonToBean(String json,Class<T> class1) throws InstantiationException, IllegalAccessException{  Gson gson = new Gson();  T t = class1.newInstance();  t=gson.fromJson(json, class1);  return t;  }  /** * 将json字符串转换成一个json对象 * @param str * @return */  public static JSONObject stringToJson(String str){  try {  return new JSONObject(str);  } catch (JSONException e) {  e.printStackTrace();  return null;  }  }  public static String getString(InputStream is){  try {  ByteArrayOutputStream baos = new ByteArrayOutputStream();  byte[] buffer = new byte[1024];  int len = -1;  while((len = is.read(buffer)) != -1){  baos.write(buffer, 0, len);  }  byte[] byteArray = baos.toByteArray();  //String str = new String(byteArray);  return new String(byteArray,"utf-8");  } catch (IOException e) {  e.printStackTrace();  }  return "";  }  /** * 从assert文件夹中读取json文件,然后转化为json对象 * @throws Exception  */  public static JSONObject getJsonDataFromAssets(Context context,String jsonFileName) throws Exception{  JSONObject mJsonObj = null;  StringBuffer sb = new StringBuffer();  InputStream is = context.getAssets().open(jsonFileName);  int len = -1;  byte[] buf = new byte[1024];  while ((len = is.read(buf)) != -1){  sb.append(new String(buf, 0, len, "UTF-8"));  }  is.close();  mJsonObj = new JSONObject(sb.toString());  return mJsonObj;  }  }  

10、http请求类

/** * http  请求工具类 * @author winfo-wj * */
public class HttpRequest {  private static HttpUtils http = new HttpUtils();  /** * 请求回调接口 * @author winfo-wj * */  public interface RequestCallBackListener{  /** * 请求成功  * @param resultData    服务器返回的结果数据 */  public void onSuccess(String resultData);  /** * 请求失败 * @param error 错误信息 */  public void onFailure(String error);  }  /** * get请求  * @param url 请求路径 * @param requestCallBackListener 请求回调 */  public static void get(String url , final RequestCallBackListener requestCallBackListener){  http.configTimeout(1000*10);  http.send(HttpMethod.GET, url, new RequestCallBack<String>() {  @Override  public void onSuccess(ResponseInfo<String> response) {  requestCallBackListener.onSuccess(response.result);  }  @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、通知栏的布局

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

13、按本更新提示的对话框布局文件

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

14对话框按钮的.9图

15、

<!-- 黑色 --><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><!-- 小号字体大小 -->

转载于:https://www.cnblogs.com/wenjie123/p/5512853.html

android应用版本更新功能---完整版相关推荐

  1. 通用(任何android机型)Root教程(完整版!附砖机自救方法)转自安卓网

    通用(任何android机型)Root教程(完整版!附砖机自救方法)转自安卓网 2012年01月02日 一台android终端(可能是手机.可能是平板,也可能是其它),很多功能是要取得Root权限后才 ...

  2. appinventor mysql_利用AppInventor实现登录功能(完整版).docx

    利用AppInventor实现登录功能(完整版) 上次教程,我们已经在SAE的共享型MySQL中新建了数据表,并且通过APP向数据表中写入了用户的信息(用户名.密码.昵称),如下图所示: ?????? ...

  3. 清华大学计算机系毕业论文 android,计算机专业毕业论文完整版.doc

    计算机专业毕业论文完整版 摘要 随着信息技术的高速发展,21世纪是数字信息时代,互联网正以前所未有的冲击力影响着人类的生活.它的出现和发展,同样也为学校的发展提供了丰富的资源.正是在这样的趋势下,大部 ...

  4. 购物车功能完整版12.13

    一.这次系统来做了下购物车的功能模块,以下几个功能吧: 1.查询购物车列表 2.向购物车添加商品 3.删除购物车商品 4.修改购物车商品数量 以上四个是传统的增删改成功能. 5.购物车商品全选功能实现 ...

  5. springboot 微信小程序 对接微信支付功能(完整版)

    微信小程序对接微信支付功能 业务流程时序图 JAVA版 1. 项目架构 2. pom.xml配置文件 3. 小程序账号参数配置类 4.JAVA 通用代码 4.1 工具类 4.1.1 IdGen (id ...

  6. wangEditor 修改 “视频”菜单 的实现方式,达到上传视频的功能---完整版

    //经测,没能实现我的需求,我经二次修改实现,仅先修改了构造函数 UploadVideo 里面的些许判断,下面链接为我改过的 https://blog.csdn.net/m0_37885651/art ...

  7. android+客户端+教程,Android新浪客户端开发教程完整版.pdf

    Android新浪客户端开发教程完整版 Android 新浪客户端开发教程新浪客户端开发教程 (完整版(完整版)) 新浪客户端开发教程新浪客户端开发教程 ((完整版完整版)) android开发我的新 ...

  8. Android掌中游斗地主游戏源码完整版

    源码大放送-掌中游斗地主(完整版),集合了单机斗地主.网络斗地主.癞子斗地主等,有史以来最有参考价值的源码,虽然运行慢了一点但是功能正常,用的是纯java写的. 项目详细说明:http://andro ...

  9. HUAWEI被google禁完整版Android的背后——中美两国的博弈。

    路透社5月20日报道称,谷歌已经暂停了与华为的部分业务往来. 谷歌将不再与华为开展需要转让硬件和软件产品的业务,但在开源授权范围内的除外.谷歌还将停止就安卓和谷歌服务为华为提供技术支持和协作. 对此, ...

最新文章

  1. Linux安装HDF5及遇到的问题总结
  2. 腾讯首次发布 AI 白皮书讲了什么?
  3. 第二次作业 郭昭杰 201731062608
  4. MATLAB 多项式
  5. 可以下载Microsoft ISA Server 2006 试用版了,网管需要关注
  6. 中国新型储能市场技术进展与投资经营模式建议分析报告2022-2028年版
  7. 使用Flow快速开发Teams小应用
  8. 带有自定义模块的JBoss EAP上的骆驼
  9. 大数据基础知识问答----hadoop篇
  10. 【java基础知识】swagger组件常用命令
  11. sklearn学习总结
  12. 系统提示System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本解决办法...
  13. spring boot actuator 如何显示详细信息
  14. Hinton 最近提出的 Capsule 计划
  15. purifier 常用配置 保留 id 和 iframe
  16. 安卓客户端开发!如何试出一个Android开发者真正的水平?分享PDF高清版
  17. 原腾讯副总裁,Google资深研究员吴军:ChatGPT不算新技术革命,带不来什么新机会...
  18. mysql 查询数据库ip_如何查看连接MYSQL数据库的IP信息
  19. 强力解决npm各种大姨妈
  20. 将虚拟机VMware从C盘移动到E盘

热门文章

  1. CVPR | 基于LiDAR的3D物体检测新框架
  2. Python解决print()不换行问题
  3. 一道简单的sql语句题
  4. Numpy基础知识点汇总
  5. 深度学习(三十五)异构计算GLSL学习笔记(1)
  6. 如何写标题摘要关键字
  7. 使用 加载 顺序_SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣
  8. java实现米和厘米比较好_java如何根据实际经、纬度和已知经、纬度做对比,计算出具体偏差米数。(以米为单位)...
  9. centos7 mysql 5.5.27_centos7上安装mysql-5.7.27
  10. axios在派遣方法时候的异步