您的位置:首页 > 移动开发 > Android开发

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

2016-05-20 17:19 806 查看






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

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

1、检测是否有新版本

public class MainActivity extends Activity {

private Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

button = (Button) findViewById(R.id.button1);

button.setOnClickListener(new OnClickListener() {

@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、版本检测的工具类

/**
*
* @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、增加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() {
@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、版本检测的状态类

/**
*
* @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;//文件的总长度

@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, "xxx");
// 更改文字
notification.contentView.setTextViewText(R.id.bartext, "检测到新版本已经下载完成,点击即安装!");
// 隐藏进度条
notification.contentView.setViewVisibility(R.id.progressBar1, View.GONE);

Intent intent = ApkUtils.getInstallIntent(updateFile);
PendingIntent pendingIntent = PendingIntent.getActivity(UpdateVersionService.this, 0, intent, 0);
notification.flags = Notification.FLAG_AUTO_CANCEL;//点击通知栏之后 消失
notification.contentIntent  = pendingIntent;//启动指定意图
}
// 发送消息
nm.notify(0, notification);
}

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

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

long l = current*100/total;
notification.contentView.setTextViewText(R.id.msg, "正在下载:xxx");
// 更改文字
notification.contentView.setTextViewText(R.id.bartext, l+ "%");
// 更改进度条
notification.contentView.setProgressBar(R.id.progressBar1, 100,(int)l, false);
// 发送消息
nm.notify(0, notification);

//              Intent intent = new Intent();
//                intent.setAction("cancel");
//                PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
//                notification.contentView.setOnClickPendingIntent(R.id.btnStartStop, pendingIntent);

}

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

});
}

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

@Override
public void onDestroy() {
//下载完成时,清楚该通知,自动安装
nm.cancel(titleId);
System.out.println("UpdateVersionService----onDestroy");
//        try {
//            GdmsaecApplication.db.deleteAll(VersionInfo.class);
//        } catch (DbException e) {
//            e.printStackTrace();
//        }
super.onDestroy();
}

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


5、吐司的工具类

public class ToastUtils {

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


6、获取sdcard根目录

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

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

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


7、版本检测的实体类

public class VersionInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private 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><!-- 小号字体大小 -->
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: