在AndroidManifest.xml里定义了每个Android apk的版本标识:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.month01"
android:versionCode="1"
android:versionName="1.0" >
其中:android:versionCode和android:versionName两个字段分别表示版本代码,版本名称。versionCode是整型数字,versionName是字符串。由于version是给用户看的,不太容易比较大小,升级检查时,可以以检查versionCode为主,方便比较出版本的前后大小。
一、连网权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
二、版本更新信息的封装
/**
* 版本更新信息的封装
*/
public class UpdateEntity {
private String versionCode;
private String downloadUrl;
private String updateLog;
public String getVersionCode() {
return versionCode;
}
public String getDownloadUrl() {
return downloadUrl;
}
public String getUpdateLog() {
return updateLog;
}
public void setUpdateLog(String updateLog) {
this.updateLog = updateLog;
}
public void setVersionCode(String versionCode) {
this.versionCode = versionCode;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
}
三、获取服务器的更新内容
package gengxin.my_version;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import java.io.File;
import java.io.InputStream;
/**
* 获取服务器的更新内容
*
* 当前版本 apk的路径
*
* 更新细则
*/
public class UpdateTools {
/*
* 用pull解析器解析服务器返回的xml文件 (xml封装了版本号)
*/
public static UpdateEntity getUpdataInfo(InputStream is) throws Exception {
XmlPullParser parser = Xml.newPullParser();
// 设置解析的数据源
parser.setInput(is, "utf-8");
int type = parser.getEventType();
// 实体
UpdateEntity info = new UpdateEntity();
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if ("versionCode".equals(parser.getName())) {
// 获取版本号
info.setVersionCode(parser.nextText());
} else if ("downloadUrl".equals(parser.getName())) {
// 获取要升级的APK文件
info.setDownloadUrl(parser.nextText());
} else if ("updateLog".equals(parser.getName())) {
// 获取该文件的信息
info.setUpdateLog(parser.nextText());
}
break;
}
type = parser.next();
}
return info;
}
/**
*
* 安装Apk
*
* @param file
* @param context
*/
public void installApk(File file, Context context) {
Intent intent=new Intent();
//执行动作
intent.setAction(Intent.ACTION_VIEW);
//执行的数据类型
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
context.startActivity(intent);
}
}
四、匹配、下载、自动安装:
package gengxin.my_version;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.os.Handler;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private UpdateEntity updateEntity;
private AlertDialog.Builder builder;
/**
* 版本更新的Hnadler
*/
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
builder.setMessage(updateEntity.getUpdateLog());
builder.show();
break;
case 1:
downLoadApk();
break;
}
}
;
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void button(View v) {
builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("更新").setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.sendEmptyMessage(1);
}
}).setNegativeButton("以后再说", null).create();
// 开启线程检查版本信息
new Thread(new CheckVersionTask()).start();
}
/*
* 从服务器中下载APK
*/
protected void downLoadApk() {
final ProgressDialog pd; // 进度条对话框
pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("正在下载更新");
pd.show();
new Thread() {
@Override
public void run() {
try {
File file = getFileFromServer(
updateEntity.getDownloadUrl(), pd);
sleep(3000);
UpdateTools tools = new UpdateTools();
// 安装APk
tools.installApk(file, MainActivity.this);
pd.dismiss(); // 结束掉进度条对话框
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 下载方法
*
* @param path
* @param pd
* @return
* @throws Exception
*/
public File getFileFromServer(String path, ProgressDialog pd)
throws Exception {
// 如果相等的话表示当前的sdcard挂载在手机上并且是可用的
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
// 获取到文件的大小
pd.setMax(conn.getContentLength());
InputStream is = conn.getInputStream();
File file = new File(Environment.getExternalStorageDirectory(),
"updata.apk");
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
int total = 0;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
total += len;
// 获取当前下载量
pd.setProgress(total);
float i1 = total / 1024;//正在下载换算成 kb
final float i = conn.getContentLength() / 1024 / 1024;//总数换算成 M
pd.setProgressNumberFormat(String.format("%.2fkb/%.2fM", i1, i));//换算
}
fos.close();
bis.close();
is.close();
return file;
} else {
return null;
}
}
//内部类
public class CheckVersionTask implements Runnable {
public void run() {
try {
// 从资源文件获取服务器 地址
String path = "http://www.oschina.net/MobileAppVersion.xml";
// 包装成url的对象
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setConnectTimeout(5000);
InputStream is = conn.getInputStream();
updateEntity = UpdateTools.getUpdataInfo(is);
// 当前版本号
int versionCode = MainActivity.this.getPackageManager()
.getPackageInfo(MainActivity.this.getPackageName(), 0).versionCode;
if (Integer.parseInt(updateEntity.getVersionCode()) <= versionCode) {
Log.i("xxx", "版本号相同无需升级");
} else {
Log.i("xxxx", "版本号不同 ,提示用户升级 ");
handler.sendEmptyMessage(0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}