当初做app更新时,网上找了很多方法,看了很多博客,都没有解决问题。别人的博文,大体只有两种内容。一种是把version.xml放到项目src目录下, 如下方法,获得字符流,然后解析成包含version,name,url的HashMap。然后
mHashMap.get("version")
获得版本比较更新 。
InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");
ParseXmlService service = new ParseXmlService();
mHashMap = service.parseXml(inStream);
这类博文没有解决问题,我们做更新,大都是从网上获取版本信息,而他没有写如何从网上获取version.xml。
还有一类,是这样:
try {
// 把version.xml放到网络上,然后获取文件信息
URL url = new URL(updateVersionXMLPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5 * 1000);
conn.setRequestMethod("GET");// 必须要大写
InputStream inputStream = conn.getInputStream();
// 解析XML文件。
ParseXmlService service = new ParseXmlService();
hashMap = service.parseXml(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
实测,不会得到hashMap。后来猜测,可能是inputStream的格式问题,查了各种字符流,无果。后来又试图把inputStream转成String,转成file。发现在HttpURLConnection这里,程序就跳出了。
废话不多说了,接下来是重点,告诉大家,我是如何解决的:(有没有写到的地方,就是别人写过的,建议有不懂的,可以先看下别人的博文)
首先,服务器上有一个xml文件:
http://m.xylbh.cn/android.xml
<?xml version="1.0" encoding="utf-8"?>
<update>
<version>8</version>
<name>测试1.0.1</name>
<url>http://m.xylbh.cn/xyl.apk</url>
</update>
上诉xml链接,大家可以直接用来测试。apk文件我出于安全考虑,我已混淆。
然后,我建了一个下载xml文件的线程,保存到sd卡(如果没有就是手机内存根目录),命名为android:
private class downloadXmlThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
try {
// 判断SD卡是否存在,并且是否具有读写权限
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
// 获得存储卡的路径
String sdpath = Environment.getExternalStorageDirectory() + "/";
mSavePath = sdpath + "download";
URL url = new URL("http://m.xylbh.cn/android.xml");
// 创建连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
// 创建输入流
InputStream in = conn.getInputStream();
File file = new File(mSavePath);
// 判断文件目录是否存在
if (!file.exists()) {
file.mkdir();
}
File xmlFile = new File(mSavePath, "android");
FileOutputStream fos = new FileOutputStream(xmlFile);
// 缓存
byte buf[] = new byte[1024];
// 写入到文件中
do {
int numread = in.read(buf);
if (numread <= 0) {
// 下载完成
break;
}
// 写入文件
fos.write(buf, 0, numread);
} while (!cancelUpdate);// 点击取消就停止下载
fos.close();
in.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后我会在程序打开,判断更新的时候,启动线程。
/**
* 检查软件是否有更新版本
*/
private boolean isUpdate() {
// 下载xml
downloadXml();
int versionCode = getVersionCode(mContext);
if (serviceVersion > versionCode) {
return true;
}
return false;
}
private void downloadXml() {
new downloadXmlThread().start();
}
这里的serviceVersion我是在构造函数里传过来的
public UpdateManager(Context context, int serviceVersion) {
this.mContext = context;
this.serviceVersion = serviceVersion;
}
在MainAcitvity的onCreate方法中判断更新的时候,首先打开sd卡中的android文件,转化成String,然后获得version信息(这里方法特别笨,看下边):
private int getVersionFromString(){//获得版本信息
String xml = readFromFile();
String s1 = "0";
if(xml.length()>60){
s1=xml.substring(58,59); //第58到59的数是版本(-_-!)
}
int version = Integer.parseInt(s1);//注意,不是getInteger()
return version;
}
private String readFromFile(){//获得文件转化成的字符串
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
String foldername = Environment.getExternalStorageDirectory().getPath()+ "/eryaApp";
File folder = new File(foldername);
if (folder == null || !folder.exists()) {
folder.mkdir();
}
String sdpath = Environment.getExternalStorageDirectory() + "/" + "download/android";
File targetFile=new File(sdpath);
String readedStr="";
try{
if(!targetFile.exists()){
targetFile.createNewFile();
return "No File error ";
}else{
InputStream in = new BufferedInputStream(new FileInputStream(targetFile));
BufferedReader br= new BufferedReader(new InputStreamReader(in, "UTF-8"));
String tmp;
while((tmp=br.readLine())!=null){
readedStr+=tmp;
}
br.close();
in.close();
return readedStr;
}
} catch (Exception e) {
// Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
return e.toString();
}
}else{
// Toast.makeText(context,"未发现SD卡!",Toast.LENGTH_LONG).show();
return "SD Card error";
}
}
onCreate方法中建线程,隔5秒再检查更新
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
UpdateManager manager = new UpdateManager(MainActivity.this,getVersionFromString());
manager.checkUpdate();
// String tu = XMLParser.getXmlFromUrl(UPDATEVERSIONXMLPATH);
}
}, 5000);// 5秒之后执行
重要的已经说完了,如果下载apk这块不懂,可以参考别人的博文,我不转载。如果有其他问题,请留言。