在Android 下写一个检测软件版本号 以自动升级APP 的插件
直接上图上代码:
1、插件类的编写
工程目录结构图:
代码如下:
package org.apache.cordova.versionupdate; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; public class GCAppPlugin extends CordovaPlugin { @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if ("version".equals(action)) { version(callbackContext); return true; } return false; } private synchronized void version(CallbackContext callbackContext) { PackageInfo packInfo; try { packInfo = this.cordova.getActivity().getPackageManager().getPackageInfo(this.cordova.getActivity().getPackageName(),0); String version = packInfo.versionName +"_"+packInfo.versionCode+""; callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, version)); } catch (NameNotFoundException e) { } } }
Javascript如何得到插件调用后的返回结果?主要通过类似 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, version)); 代码返回PluginResult,失败和成功都可以触发Javascript执行对应的自定义函数。
2、插件的配置
打开res/xml/config.xml文件,添加feature,必须匹配类名,因为源码中是通过这些去配对的。上面我们写了更新插件,现在就是要配置一下这个插件类到功能名称,我在配置文件中加入了下文粗体部分内容(最后面)。
<?xml version='1.0' encoding='utf-8'?> <widget id="com.lambda.client.cordova.washcarshopmanager" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <preference name="loglevel" value="DEBUG" /> <allow-intent href="market:*" /> <name>WashCarShopManager</name> <description> A sample Apache Cordova application that responds to the deviceready event. </description> <author email="dev@cordova.apache.org" href="http://cordova.io"> Apache Cordova Team </author> <!-- <content src="index.html" /> --> <!-- <content src="test/check_version.html" /> --> <content src="vipapp/index.html" /> <access origin="*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="sms:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <allow-navigation href="http: //*/*" /> <feature name="Whitelist"> <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" /> <param name="onload" value="true" /> </feature> <feature name="Device"> <param name="android-package" value="org.apache.cordova.device.Device" /> </feature> <feature name="NetworkStatus"> <param name="android-package" value="org.apache.cordova.networkinformation.NetworkManager" /> </feature> <feature name="Geolocation"> <param name="android-package" value="org.apache.cordova.geolocation.Geolocation" /> </feature> <feature name="Camera"> <param name="android-package" value="org.apache.cordova.camera.CameraLauncher" /> </feature> <feature name="File"> <param name="android-package" value="org.apache.cordova.file.FileUtils" /> <param name="onload" value="true" /> </feature> <feature name="Notification"> <param name="android-package" value="org.apache.cordova.dialogs.Notification" /> </feature> <feature name="SplashScreen"> <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" /> <param name="onload" value="true" /> </feature> <feature name="Gcapp"> <param name="android-package" value="org.apache.cordova.versionupdate.GCAppPlugin" /> </feature> </widget>
代码贴完了,我还是要再多说一下,
① org.apache.cordova.versionupdate.GCAppPlugin 是插件的全类名。
② Gcapp是 feature 名称,下面大家就知道在哪里会用到了
以上文件就是告诉cordova,我们新增了一个Gcapp功能,这个功能会调用我们的原生插件Java对象,接下来就是Javascript如何能调用到这个类了,最重要的就是这个Gcapp功能名称。
我们接着就要写Javascript代码来调用这个功能了,如何写呢?继续往下看,我在assets/www/plugins/下新增目录并建立了文件gcapp.js,完整路径是 assets/www/plugins/cordova-plugin-versionupdate/gcapp.js,代码如下:
cordova.define('org.apache.cordova.versionupdate.gcapp', function(require, exports, module) { var exec = require("cordova/exec"); function Gcapp() {}; Gcapp.prototype.version = function (getversion) { exec(getversion, null, 'Gcapp', 'version', []); }; Gcapp.prototype.checkUpdate = function () { exec(null, null, 'Gcapp', 'checkUpdate', []); }; var gcapp = new Gcapp(); module.exports = gcapp; });
exec是cordova.js中内部的函数,当插件返回 PluginResult.Status.OK 时会执行exec的成功回调函数,如果插件返回的是错误,则会执行exec的错误回调函数。这里我们解释一下
exec(null, null, 'Gcapp', 'checkUpdate', []);
其中Gcapp就是我们在上一步骤加的feature名称,大小写匹配着写,通过这个名称,cordova才能找到调用那个java插件类,然后通过checkUpdate知道调用这个插件类的哪个方法,后面[]中则是参数。因为我这个插件不需要参数,所以为空。
Javascript插件类也配对成功了,那如何调用呢?你可以直接在html中包括这个js,不过我们一般会再配置一个js,那就是assets/www/cordova_plugins.js(如下代码标蓝部分),这样就不用对每个插件类都去写一遍了,cordova会遍历你的配置去加载它们。
cordova.define('cordova/plugin_list', function(require, exports, module) { module.exports = [ { "file": "plugins/cordova-plugin-whitelist/whitelist.js", "id": "cordova-plugin-whitelist.whitelist", "runs": true }, { "file": "plugins/cordova-plugin-device/www/device.js", "id": "cordova-plugin-device.device", "clobbers": [ "device" ] }, { "file": "plugins/cordova-plugin-network-information/www/network.js", "id": "cordova-plugin-network-information.network", "clobbers": [ "navigator.connection", "navigator.network.connection" ] }, { "file": "plugins/cordova-plugin-network-information/www/Connection.js", "id": "cordova-plugin-network-information.Connection", "clobbers": [ "Connection" ] }, { "file": "plugins/cordova-plugin-geolocation/www/android/geolocation.js", "id": "cordova-plugin-geolocation.geolocation", "clobbers": [ "navigator.geolocation" ] }, { "file": "plugins/cordova-plugin-geolocation/www/PositionError.js", "id": "cordova-plugin-geolocation.PositionError", "runs": true }, { "file": "plugins/cordova-plugin-camera/www/CameraConstants.js", "id": "cordova-plugin-camera.Camera", "clobbers": [ "Camera" ] }, { "file": "plugins/cordova-plugin-camera/www/CameraPopoverOptions.js", "id": "cordova-plugin-camera.CameraPopoverOptions", "clobbers": [ "CameraPopoverOptions" ] }, { "file": "plugins/cordova-plugin-camera/www/Camera.js", "id": "cordova-plugin-camera.camera", "clobbers": [ "navigator.camera" ] }, { "file": "plugins/cordova-plugin-camera/www/CameraPopoverHandle.js", "id": "cordova-plugin-camera.CameraPopoverHandle", "clobbers": [ "CameraPopoverHandle" ] }, { "file": "plugins/cordova-plugin-file/www/DirectoryEntry.js", "id": "cordova-plugin-file.DirectoryEntry", "clobbers": [ "window.DirectoryEntry" ] }, { "file": "plugins/cordova-plugin-file/www/DirectoryReader.js", "id": "cordova-plugin-file.DirectoryReader", "clobbers": [ "window.DirectoryReader" ] }, { "file": "plugins/cordova-plugin-file/www/Entry.js", "id": "cordova-plugin-file.Entry", "clobbers": [ "window.Entry" ] }, { "file": "plugins/cordova-plugin-file/www/File.js", "id": "cordova-plugin-file.File", "clobbers": [ "window.File" ] }, { "file": "plugins/cordova-plugin-file/www/FileEntry.js", "id": "cordova-plugin-file.FileEntry", "clobbers": [ "window.FileEntry" ] }, { "file": "plugins/cordova-plugin-file/www/FileError.js", "id": "cordova-plugin-file.FileError", "clobbers": [ "window.FileError" ] }, { "file": "plugins/cordova-plugin-file/www/FileReader.js", "id": "cordova-plugin-file.FileReader", "clobbers": [ "window.FileReader" ] }, { "file": "plugins/cordova-plugin-file/www/FileSystem.js", "id": "cordova-plugin-file.FileSystem", "clobbers": [ "window.FileSystem" ] }, { "file": "plugins/cordova-plugin-file/www/FileUploadOptions.js", "id": "cordova-plugin-file.FileUploadOptions", "clobbers": [ "window.FileUploadOptions" ] }, { "file": "plugins/cordova-plugin-file/www/FileUploadResult.js", "id": "cordova-plugin-file.FileUploadResult", "clobbers": [ "window.FileUploadResult" ] }, { "file": "plugins/cordova-plugin-file/www/FileWriter.js", "id": "cordova-plugin-file.FileWriter", "clobbers": [ "window.FileWriter" ] }, { "file": "plugins/cordova-plugin-file/www/Flags.js", "id": "cordova-plugin-file.Flags", "clobbers": [ "window.Flags" ] }, { "file": "plugins/cordova-plugin-file/www/LocalFileSystem.js", "id": "cordova-plugin-file.LocalFileSystem", "clobbers": [ "window.LocalFileSystem" ], "merges": [ "window" ] }, { "file": "plugins/cordova-plugin-file/www/Metadata.js", "id": "cordova-plugin-file.Metadata", "clobbers": [ "window.Metadata" ] }, { "file": "plugins/cordova-plugin-file/www/ProgressEvent.js", "id": "cordova-plugin-file.ProgressEvent", "clobbers": [ "window.ProgressEvent" ] }, { "file": "plugins/cordova-plugin-file/www/fileSystems.js", "id": "cordova-plugin-file.fileSystems" }, { "file": "plugins/cordova-plugin-file/www/requestFileSystem.js", "id": "cordova-plugin-file.requestFileSystem", "clobbers": [ "window.requestFileSystem" ] }, { "file": "plugins/cordova-plugin-file/www/resolveLocalFileSystemURI.js", "id": "cordova-plugin-file.resolveLocalFileSystemURI", "merges": [ "window" ] }, { "file": "plugins/cordova-plugin-file/www/browser/isChrome.js", "id": "cordova-plugin-file.isChrome", "runs": true }, { "file": "plugins/cordova-plugin-file/www/android/FileSystem.js", "id": "cordova-plugin-file.androidFileSystem", "merges": [ "FileSystem" ] }, { "file": "plugins/cordova-plugin-file/www/fileSystems-roots.js", "id": "cordova-plugin-file.fileSystems-roots", "runs": true }, { "file": "plugins/cordova-plugin-file/www/fileSystemPaths.js", "id": "cordova-plugin-file.fileSystemPaths", "merges": [ "cordova" ], "runs": true }, { "file": "plugins/cordova-plugin-dialogs/www/notification.js", "id": "cordova-plugin-dialogs.notification", "merges": [ "navigator.notification" ] }, { "file": "plugins/cordova-plugin-dialogs/www/android/notification.js", "id": "cordova-plugin-dialogs.notification_android", "merges": [ "navigator.notification" ] }, { "file": "plugins/cordova-plugin-splashscreen/www/splashscreen.js", "id": "cordova-plugin-splashscreen.SplashScreen", "clobbers": [ "navigator.splashscreen" ] }, { "file": "plugins/cordova-plugin-versionupdate/gcapp.js", "id": "org.apache.cordova.versionupdate.gcapp", "clobbers": [ "gcapp" ] } ]; module.exports.metadata = // TOP OF METADATA { "cordova-plugin-whitelist": "1.2.1", "cordova-plugin-device": "1.1.1", "cordova-plugin-network-information": "1.2.0", "cordova-plugin-geolocation": "2.1.0", "cordova-plugin-camera": "2.1.1", "cordova-plugin-file": "4.1.1", "cordova-plugin-dialogs": "1.1.0", "cordova-plugin-splashscreen": "2.1.0" } // BOTTOM OF METADATA });
file表示我们去哪里找脚本插件定义js,id是之前我们在gcapp.js中开头cordova.define中写的标识,cordova通过这个标志去找到我们的Javascript插件定义,而clobbers则是我们在前端通过什么对象名来调用这个插件。这里我写的是gcapp,则后面调用则只需要写成gcapp.checkUpdate 即可。
三、插件的调用
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Camera Example</title> <script type="text/javascript" charset="utf-8" src="../../cordova.js"></script> <script type="text/javascript" charset="utf-8" src="../js/jquery.min.js"></script> <script type="text/javascript" charset="utf-8"> // 等待PhoneGap连接设备 document.addEventListener("deviceready",onDeviceReady,false); // PhoneGap准备就绪,可以使用! function onDeviceReady() { gcapp.version(function(version){ $("#version").html("当前软件版本号为: "+version); }); } </script> </head> <body> <p id="version">version is ?</p><br/> </body> </html>
此时已经能获取APP的版本信息了,需要在服务器端设置一个最新的版本号,每次用本地的版本号和服务器端的最新版本号比较,如果本地版本号小,则提示用户升级。
本文参考:http://www.cnblogs.com/zhoujg/p/4629162.html
因为只弄通了获取软件的版本号,而检测更新那块没弄懂,所以就没写,只写了获取版本号的内容。也算是大概了解了一下cordova自定义插件编写的流程。