最近在做一个html5 的移动开发,用的是jqm和phonegap,用dw开发环境,并在新浪云上进行app的打包。但是现在由于需要做android安装程序自动下载更新,发现phonegap有下载的功能,但是没有自动安装的功能,所以只能想到用phonegap插件。用phonegap插件必须要在eclipse的开发环境下开发,搭建参考地址如下:
http://www.phonegapcn.com/developers/get-started-13/get-started搭建完毕后将phonegap.jar放到src的包下面。
下面解决两个问题,一个是下载android安装程序,利用phonegap里api,FileTransfer。注意download 只能在英文官网里找到。下载js代码如下:
// JavaScript Document
$('#login').live("pageinit", function () {
document.addEventListener("deviceready", onDeviceReady, false);//phonegap绑定backbutton和获取终端信
var sourcedir1="app";//下载一级目录
var sourcedir2="update";//下载二级目录息
//客户端下载地址
var url="http://192.168.103.58:8080/mobile/test.apk";
var source="test.apk";
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
fileSystem.root.getDirectory(
sourcedir1,
{create:true,exclusive:false},
function(entrydir){
entrydir.getDirectory(
sourcedir2,
{create:true,exclusive:false},
function(entrydir){
entrydir.getFile(
source,
{create:true,exclusive:false},
function(parent){
var fileTransfer = new FileTransfer();
var uri = encodeURI(url);
fileTransfer.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
var percentLoaded = Math.round(100 * (progressEvent.loaded / progressEvent.total));
var progressbarWidth = percentLoaded/2 + "%";
//下载进度显示,可自己定义
$.mobile.showPageLoadingMsg('a', "正在下载...... "+progressbarWidth,true);
if(progressbarWidth=100){
//设置延时
setTimeout("$.mobile.hidePageLoadingMsg()",3000);
}
} else {
loadingStatus.increment();
}
};
fileTransfer.download(
uri,
parent.fullPath,
function(entry){
//调用自动安装的插件
window.plugins.update.openFile(entry.fullPath,null,null);
},
function(error) {alert("下载失败")}
);
},
function(){alert("文件下载失败")}
);
},
function(){alert("创建二级栏目失败")}
);
},
function(){alert("创建一级目录失败");}
);
}, function(evt){
console.log("加载文件系统出现错误");
});
}
}); //pageshow
其中window.plugins.update.openFile(entry.fullPath,null,null);为调用phonegap插件js的代码,,下面解决第二个问题,即自动安装插件,该插件phonegap.jar1.9以上支持。插件js代码如下:
var Update = function(){};
Update.prototype.openFile = function(fullPath,onSuccess, onFail){
cordova.exec(onSuccess, onFail, 'Update', 'openFile', [fullPath]);
};
Update.prototype.openApp = function(packageName,onSuccess, onFail){
cordova.exec(onSuccess, onFail, 'Update', 'openApp', [packageName]);
};
if(!window.plugins) {
window.plugins = {};
}
if (!window.plugins.update) {
window.plugins.update = new Update();
}
插件的java代码如下:
import java.io.File;
import java.util.List;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.net.Uri;
public class Update extends Plugin {
@Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
PluginResult.Status status = PluginResult.Status.OK;
if (action.equals("openFile")) {
try {
openFile(new File(args.getString(0).replaceAll("file://", "")));
} catch(Exception e){
return new PluginResult(PluginResult.Status.ERROR, "打开错误");
}
}
else if(action.equals("openApp")){
try
{
if(checkApp(args.getString(0))){
openApp(args.getString(0));
}
else{
//Log.d("openApp", "没有应用");
return new PluginResult(PluginResult.Status.ERROR, "没有应用");
}
}
catch(Exception e){
//Log.d("openApp", "打开错误");
return new PluginResult(PluginResult.Status.ERROR, "错误");
}
}
return new PluginResult(status, "成功");
}
private void openApp(String packageName) throws NameNotFoundException {
PackageManager pm=this.cordova.getActivity().getPackageManager();
PackageInfo pi = pm.getPackageInfo(packageName, 0);
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
resolveIntent.setPackage(pi.packageName);
List<ResolveInfo> apps = pm.queryIntentActivities(resolveIntent, 0);
ResolveInfo ri = apps.iterator().next();
if (ri != null ) {
String packageName1 = ri.activityInfo.packageName;
String className = ri.activityInfo.name;
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName cn = new ComponentName(packageName1, className);
intent.setComponent(cn);
this.cordova.getActivity().startActivity(intent);
}
}
private boolean checkApp(String packageName) {
if (packageName == null || "".equals(packageName))
return false;
try {
ApplicationInfo info = this.cordova.getActivity().getPackageManager().getApplicationInfo(
packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
return true;
} catch (NameNotFoundException e) {
return false;
}
}
private void openFile(File f) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
/* 调用getMIMEType()来取得MimeType */
String type = getMIMEType(f);
/* 设置intent的file与MimeType */
intent.setDataAndType(Uri.fromFile(f), type);
this.cordova.getActivity().startActivity(intent);
}
/* 判断文件MimeType的method */
private String getMIMEType(File f) {
String type = "";
String fName = f.getName();
/* 取得扩展名 */
String end = fName
.substring(fName.lastIndexOf(".") + 1, fName.length())
.toLowerCase();
/* 依扩展名的类型决定MimeType */
if (end.equals("m4a") || end.equals("mp3") || end.equals("mid")
|| end.equals("xmf") || end.equals("ogg") || end.equals("wav")) {
type = "audio";
} else if (end.equals("3gp") || end.equals("mp4")) {
type = "video";
} else if (end.equals("jpg") || end.equals("gif") || end.equals("png")
|| end.equals("jpeg") || end.equals("bmp")) {
type = "image";
} else if (end.equals("apk")) {
/* android.permission.INSTALL_PACKAGES */
type = "application/vnd.android.package-archive";
} else {
type = "*";
}
/* 如果无法直接打开,就跳出软件列表给用户选择 */
if (end.equals("apk")) {
} else {
type += "/*";
}
return type;
}
}
另外还需在工程根目录res->xml中的config.xml里面配置插件信息<plugin name="Update" value="your package.Update"/>。
代码测试通过,如有疑问,欢迎大家留言指正交流。