获取版本号#
id : 驼峰式命名: 控件类型_控件的所在位置_控件表示的逻辑内容
/**
* 获取当前应用程序的版本号
* @return
*/
private String getVersionName(){
//包的管理者,获取清单文件中的所有信息
PackageManager pm = getPackageManager();
try {
//根据包名获取清单文件中的信息,其实就是返回一个保存有清单文件信息的javabean
//packageName :应用程序的包名
//flags : 指定信息的标签,0:获取基础的信息,比如包名,版本号,要想获取权限等等信息,必须通过标签来指定,才能去获取
//GET_PERMISSIONS : 标签的含义:处理获取基础信息之外,还会额外获取权限的信息
//getPackageName() : 获取当前应用程序的包名
PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
//获取版本号名称
String versionName = packageInfo.versionName;
return versionName;
} catch (NameNotFoundException e) {
//包名找不到的异常
e.printStackTrace();
}
return null;
}
连接服务器
/**
* 提醒用户更新版本
*/
private void update() {
//1.连接服务器,查看是否有最新版本, 联网操作,耗时操作,4.0以后不允许在主线程中执行的,放到子线程中执行
new Thread(){
public void run() {
try {
//1.1连接服务器
//1.1.1设置连接路径
//spec:连接路径
URL url = new URL("xxxxx");
//1.1.2获取连接操作
HttpURLConnection conn = (HttpURLConnection) url.openConnection();//http协议,httpClient
//1.1.3设置超时时间
conn.setConnectTimeout(5000);//设置连接超时时间
//conn.setReadTimeout(5000);//设置读取超时时间
//1.1.4设置请求方式
conn.setRequestMethod("GET");//post
//1.1.5获取服务器返回的状态码,200,404,500
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
//连接成功
}else{
//连接失败
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
};
}.start();
}
权限:<uses-permission android:name="android.permission.INTERNET"/>
解析json数据# ()
1.获取服务器返回的流信息
//获取服务器返回的流信息
InputStream in = conn.getInputStream();
2.将流信息转化成字符串
public class StreamUtil {
/**
* 将流信息转化成字符串
* @return
* @throws IOException
*/
public static String parserStreamUtil(InputStream in) throws IOException{
//字符流,读取流
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//写入流
StringWriter sw = new StringWriter();
//读写操作
//数据缓冲区
String str = null;
while((str = br.readLine()) !=null){
//写入操作
sw.write(str);
}
//关流
sw.close();
br.close();
return sw.toString();
}
}
3.解析json数据
//将获取到的流信息转化成字符串
String json = StreamUtil.parserStreamUtil(in);
//解析json数据
JSONObject jsonObject = new JSONObject(json);
4.获取数据
//获取数据
code = jsonObject.getString("code");
apkurl = jsonObject.getString("apkurl");
des = jsonObject.getString("des");
弹出对话框
1.因为在子线程不能更新主线程ui所以给handler发送一个,在handler中弹出对话框
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_UPDATE_DIALOG:
//弹出对话框
showdialog();
break;
}
};
};
2.弹出对话框
/**
* 弹出对话框
*/
protected void showdialog() {
AlertDialog.Builder builder = new Builder(this);
//设置对话框不能消失
builder.setCancelable(false);
//设置对话框的标题
builder.setTitle("新版本:"+code);
//设置对话框的图标
builder.setIcon(R.drawable.ic_launcher);
//设置对话框的描述信息
builder.setMessage(des);
//设置升级取消按钮
builder.setPositiveButton("升级", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
//显示对话框
//builder.create().show();//两种方式效果一样
builder.show();
}
对话框细节的处理
1.实现了取消按钮的操作
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//1.隐藏对话框
dialog.dismiss();
//2.跳转到主界面
enterHome();
}
});
2.处理了在跳转到主界面,从主界面点击返回键返回的时候,返回欢迎界面的问题,解决:在跳转的是将欢迎界面移出
/**
* 跳转到主界面
*/
protected void enterHome() {
Intent intent = new Intent(this,HomeActivity.class);
startActivity(intent);
//移出欢迎界面
finish();
}
3.处理对话框延迟显示的问题
//处理连接外网连接时间的问题
//在连接成功之后在去获取一个时间
int endTime = (int) System.currentTimeMillis();
//比较两个时间的时间差,如果小于两秒,睡两秒,大于两秒,不睡
int dTime = endTime-startTime;
if (dTime<2000) {
//睡两秒钟
SystemClock.sleep(2000-dTime);//始终都是睡两秒钟的时间
}
/**
* 3.下载最新版本
*/
protected void download() {
HttpUtils httpUtils = new HttpUtils();
//判断SD卡是否挂载
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//url : 新版本下载的路径 apkurl
//target : 保存新版本的目录
//callback : RequestCallBack
httpUtils.download(apkurl, "/mnt/sdcard/xxxx.apk", new RequestCallBack<File>() {
//现在成功调用的方法
@Override
public void onSuccess(ResponseInfo<File> arg0) {
// TODO Auto-generated method stub
}
//下载失败调用的方法
@Override
public void onFailure(HttpException arg0, String arg1) {
// TODO Auto-generated method stub
}
//显示当前下载进度操作
//total : 下载总进度
//current : 下载的当前进度
//isUploading : 是否支持断点续传
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
//设置显示下载进度的textview可见,同时设置相应的下载进度
tv_spalsh_plan.setVisibility(View.VISIBLE);//设置控件是否可见
tv_spalsh_plan.setText(current+"/"+total);//110/200
}
});
}
}
注意问题:
1.修改apkurl地址
2.增加sd操作权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3.判断sd是否挂载
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {}
4.生成2.0版本的apk
工程的bin目录下去找
a.将清单文件中的版本号改成2.0
b.重新运行
c.拷贝bin目录下的文件
/**
* 4.安装最新的版本
*/
protected void installAPK() {
/**
* <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" /> //content : 从内容提供者中获取数据 content://
<data android:scheme="file" /> // file : 从文件中获取数据
<data android:mimeType="application/vnd.android.package-archive" />
</intent-filter>
*/
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
//单独设置会相互覆盖
/*intent.setType("application/vnd.android.package-archive");
intent.setData(Uri.fromFile(new File("/mnt/sdcard/mobliesafe75_2.apk")));*/
intent.setDataAndType(Uri.fromFile(new File("/mnt/sdcard/mobliesafe75_2.apk")), "application/vnd.android.package-archive");
//在当前activity退出的时候,会调用之前的activity的onActivityResult方法
//requestCode : 请求码,用来标示是从哪个activity跳转过来
//ABC a -> c b-> c ,c区分intent是从哪个activity传递过来的,这时候就要用到请求码
startActivityForResult(intent, 0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
enterHome();
}