最近在做phoneGap的项目,想测试下用插件实现自动更新功能,代码很快整理完成了,在测试的过程中还是发现了一些问题,现在把代码整理以备后期使用。
代码分成3部分,页面调用插件js,插件类,插件工具类。
插件类:
package com.example.testhtml.update;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.util.Log;
public class UpdatePlugin extends Plugin {
private Context context;
@Override
public PluginResult execute(String arg0, JSONArray args, String arg2) {
try {
Context context = cordova.getActivity().getApplicationContext();
this.context=context;
//String versioName =new VersionUtil().getVersionName(context);
String s= args.getString(0);
this.savePath=s.replace("file://", "");
//Log.i("ss","当前文件版本: "+versioName+" "+s+" savePath: "+savePath);
saveFileName = savePath + "/AndroidHtml.apk";
boolean update =checkVersion(context);//检测版本
if(update){
upLoad();//下载更新
installApk(context);//自动安装
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
return r;
}
/**
* 检查是否需要更新程序
*
* @throws NameNotFoundException
*/
private boolean checkVersion(Context context) throws NameNotFoundException {
UpdateInfo updateInfo = new UpdateInfo();
// 先获取服务器配置文件流
InputStream in = getIn();
updateInfo = ParseXmlUtils.parseXml(in);
apkUrl = updateInfo.getUrl();
Log.i("apkurl", updateInfo.getUrl()+" "+updateInfo.getVersion()+" "+updateInfo.getDescription());
System.out.println(updateInfo.getVersion()+" ssssssssss "+VersionUtil.getVersionName(context));
if (updateInfo.getVersion().equals(VersionUtil.getVersionName(context))) {
return false;
}
return true;
}
// 获取服务器配置文件流
public InputStream getIn() {
HttpGet httpGet = new HttpGet(
"http://192.168.0.10/update/UpdateXml.xml");
HttpParams hp = httpGet.getParams();
hp.getParameter("true");
HttpClient hc = new DefaultHttpClient();
try {
HttpResponse ht = hc.execute(httpGet);
if (ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity he = ht.getEntity();
InputStream is = he.getContent();
return is;
} else {
Log.e("ksk", "error");
return null;
}
} catch (ClientProtocolException e) {
Log.e("ksk", e.toString());
return null;
} catch (IOException e) {
Log.e("ksk", e.toString());
return null;
}
}
boolean interceptFlag = false;
private String savePath = "";
private String saveFileName = "";
private String apkUrl;
public void upLoad(){
try {
Log.i("sssss123",apkUrl+"wwws"+" "+savePath+" "+saveFileName);
//apkUrl="http://192.168.0.10/update/updateHTML.apk";
URL url2 = new URL(apkUrl);
HttpURLConnection conn = (HttpURLConnection) url2
.openConnection();
InputStream is = conn.getInputStream();
Log.i("savePath",savePath);
File file = new File(savePath);
if (!file.exists()) {
file.mkdir();
}
String apkFile = saveFileName;
Log.i("apkFile",apkFile);
File ApkFile = new File(apkFile);
if (!ApkFile.exists()) {
ApkFile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(ApkFile);
byte buf[] = new byte[1024];
do {
int numread = is.read(buf);
if (numread <= 0){//读取完成后,直接退出
break;
}
fos.write(buf, 0, numread);
} while (!interceptFlag);// 点击取消就停止下载.
fos.close();
is.close();
} catch (MalformedURLException e) {
Log.e("ksk", e.toString());
} catch (IOException e) {
Log.e("ksk", e.toString());
}
}
private void installApk(Context context) {
File apkfile = new File(saveFileName);
if (!apkfile.exists()) {
return;
}
//Uri uri = Uri.fromFile(new File(apkfile.toString()));
Intent i = new Intent(android.content.Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(new File("/storage/sdcard0/download_test/AndroidHtml.apk"));
//不能用这个,否则打开失败i.setDataAndType(Uri.parse("/storage/sdcard0/download_test/AndroidHtml.apk"),"application/vnd.android.package-archive");
i.setDataAndType(uri,"application/vnd.android.package-archive");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setAction(android.content.Intent.ACTION_VIEW);
context.startActivity(i);
/*Uri uri = Uri.fromFile(new File(apkfile.toString()));
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
context.startActivity(intent);*/
}
}
插件工具类:
package com.example.testhtml.update;
import java.io.Serializable;
/**
* 更新信息实体类 UpdateInfo.java
*
*/
public class UpdateInfo implements Serializable {
private String version; // 版本号
private String url; // 新版本存放url路径
private String description; // 更新说明信息,比如新增什么功能特性等
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
package com.example.testhtml.update;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
/**
* 版本检测工具类 VersionUtil.java
*
*/
public class VersionUtil {
/**
* 获取版本号
*
* @param context
* 上下文
* @return
* @throws NameNotFoundException
*/
public static String getVersionName(Context context)
throws NameNotFoundException {
// 获取PackageManager 实例
PackageManager packageManager = context.getPackageManager();
// 获得context所属类的包名,0表示获取版本信息
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
return packageInfo.versionName;
}
}
package com.example.testhtml.update;
import java.io.InputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.util.Log;
/**
* 解析Xml文件 ParseXmlUtils.java
*
*/
public class ParseXmlUtils {
/**
* 通过InputStream 解析文件
*
* @param in
* @return
*/
public static UpdateInfo parseXml(InputStream in) {
UpdateInfo updateInfo = new UpdateInfo();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
Document doc = null;
doc = db.parse(in);
Element root = doc.getDocumentElement();
NodeList resultNode = root.getElementsByTagName("info");
for (int i = 0; i < resultNode.getLength(); i++) {
Element res = (Element) resultNode.item(i);
//Log.i("sskiuh", res.getChildNodes().getLength()+" "+res+" "+i);
if(i==0){
updateInfo.setVersion(res.getElementsByTagName("version").item(0).getFirstChild().getNodeValue());
//Log.i("sdf",res.getElementsByTagName("version").item(0).getFirstChild().getNodeValue());
}else if(i==1){
updateInfo.setUrl(res.getElementsByTagName("url").item(0).getFirstChild().getNodeValue());
}else if(i==2){
updateInfo.setDescription(res.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return updateInfo;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<info>
<version>1.0</version>
</info>
<info>
<url>http://192.168.0.10/update/updateHTML.apk</url>
</info>
<info>
<description>测试版本升级</description>
</info>
</xml>
页面js
//apk自动跟新
function updateAPK(){
try {
var array = [];
array[0] = window.appRootDir.fullPath;
alert(array[0]);
cordova.exec(function(message) {
}, null, "UpdatePlugin", "update", array);
} catch(e) {
alert("错误"+e.message);
}
}