Cordova webapp实战开发:(5)如何写一个Andorid下自动更新的插件?

在 《Cordova webapp实战开发:(4)Android环境搭建》中咱们搭建好了开发环境,也给你们布置了调用插件的预习做业,作得如何了呢?今天咱们来学一下如何本身从头创建一个Andorid下的cordova插件。html

本次练习你能学到的

  1. 学习如何实现Android下自动更新功能
  2. 学习Android下插件类的编写
  3. 学习Android下插件的配置
  4. 学习Android下插件的调用

主要内容

  • 打开APP后检查版本更新,若是有更新则弹出更新对话框

  • APP中【检查更新】显示当前版本号,并能够点击进行版本检查更新

 

如何实现自动更新功能

你能够本身写代码,也能够网上找代码抄一下,我以前的 敏捷我的APP 就是从网上下的一个代码片断放进个人项目中的。不过今天和你们说的不是如何编写自动更新代码,由于咱们今天要作的是如何更快的用别人写好的东西来加速本身产品开发的进度和质量。前端

自动更新这个东西也不涉及到什么技术难度,通常第三方要是提供了也不会出什么质量问题,可以拿来就用岂不是很好呢?网上找了一下,发现 友盟提供自动更新java

 

 

很好,那就直接用这个吧,Andorid和iOS均可以用。android

如何集成到咱们的产品中,看他们本身写的文档:自动更新android文档 ,我就很少说了,若是遇到问题,能够在我们群里问问你们。web

插件类的编写

原生Andorid中若是调用,就看上面说的他们本身写的文档。若是咱们如今要在APP中【设置】中增长自动检查和显示当前版本,则须要咱们开始学习如何编写cordova插件了。apache

这里咱们会编写一个插件,两个方法,一个方法用来检测更新,另外一个方法用来得到当前APP的版本号。app

闲话不说了,直接来代码。webapp

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;
        }
        else if ("checkUpdate".equals(action)) {
            final Context mContext = this.cordova.getActivity();
            UmengUpdateAgent.setUpdateAutoPopup(false);
            UmengUpdateAgent.setUpdateListener(new UmengUpdateListener() {
                @Override
                public void onUpdateReturned(int updateStatus, UpdateResponse updateInfo) {
                      switch (updateStatus) {
                        case UpdateStatus.Yes: // has update
                            UmengUpdateAgent.showUpdateDialog(mContext, updateInfo);
                            break;
                        case UpdateStatus.No: // has no update
                            Toast.makeText(mContext, "如今使用的已经是最新版本了", Toast.LENGTH_SHORT).show();
                            break;
                        case UpdateStatus.NoneWifi: // none wifi
                            Toast.makeText(mContext, "没有wifi链接, 只在wifi下更新", Toast.LENGTH_SHORT).show();
                            break;
                        case UpdateStatus.Timeout: // time out
                            Toast.makeText(mContext, "超时", Toast.LENGTH_SHORT).show();
                            break;
                        }                    
                }
            });
            UmengUpdateAgent.forceUpdate(mContext);
            return true;
        } 
}

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) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

Javascript如何获得插件调用后的返回结果?主要经过相似 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, version)); 代码返回PluginResult,失败和成功均可以触发Javascript执行对应的自定义函数ide

插件的配置

插件写完了,不少人遇到的下一个问题就是怎么配置才能在Javascript中调用呢?咱们今天也不解析源码,为何呢?由于我没看:)不过,我必定要给你们说清楚如何配置,不然就永远调用不了插件。函数

打开res/xml/config.xml文件,添加feature,必须匹配类名,由于源码中是经过这些去配对的。上面咱们写了更新插件,如今就是要配置一下这个插件类到功能名称,我在配置文件中加入了下文粗体部份内容

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.glodon.gcapp" version="2.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>掌中广材</name>
    <description> 随时随地查找全国最完整最及时的信息价   </description>
    <author email="22626496@qq.com" href="http://www.中国信息价.cn">  周金根    </author>
    <content src="html/scj/scj.html" />
    <access origin="*" />
    <access origin="tel:*" launch-external="yes"/>
    <access origin="geo:*" launch-external="yes"/>
    <access origin="mailto:*" launch-external="yes"/>
    <access origin="sms:*" launch-external="yes"/>
    <access origin="market:*" launch-external="yes"/>
    
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="30000" />
    <preference name="SplashMaintainAspectRatio" value="false" />    
    <preference name="LoadingDialog" value="正在加载中..." />
    
    <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="SplashScreen"> 
        <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" />
    </feature>    
    <feature name="Camera">
        <param name="android-package" value="org.apache.cordova.camera.CameraLauncher" />
    </feature>    
    <feature name="BarcodeScanner">
        <param name="android-package" value="com.phonegap.plugins.barcodescanner.BarcodeScanner" />
    </feature>
 <feature name="Gcapp"> <param name="android-package" value="com.gldjc.guangcaiclient.GCAppPlugin" /> </feature>  
</widget>

代码贴完了,我仍是要再多说一下,

  • com.gldjc.guangcaiclient.GCAppPlugin  是插件类的全面
  • Gcapp是 feature 名称,下面你们就知道在哪里会用到了

以上文件就是告诉cordova,咱们新增了一个Gcapp功能,这个功能会调用咱们的原生插件Java对象,接下来就是Javascript如何能调用到这个类了,最重要的就是这个Gcapp功能名称。

咱们接着就要写Javascript代码来调用这个功能了,如何写呢?继续往下看,我在assets/www/plugins/下新增目录并创建了文件gcapp.js,完整路径是 assets/www/plugins/com.gldjc.guangcaiclient/www/gcapp.js,代码以下:

cordova.define('com.gldjc.guangcaiclient.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/org.apache.cordova.device/www/device.js",
        "id": "org.apache.cordova.device.device",
        "clobbers": [
            "device"
        ]
    },
    {
        "file": "plugins/org.apache.cordova.networkinformation/www/network.js",
        "id": "org.apache.cordova.networkinformation.network",
        "clobbers": [
            "navigator.connection",
            "navigator.network.connection"
        ]
    },
     {
        "file": "plugins/org.apache.cordova.networkinformation/www/Connection.js",
        "id": "org.apache.cordova.networkinformation.Connection",
        "clobbers": [
            "Connection"
        ]
    },
     {
        "file": "plugins/org.apache.cordova.splashscreen/www/splashscreen.js",
        "id": "org.apache.cordova.splashscreen",
        "clobbers": [
            "navigator.splashscreen"
        ]
    },
        {
        "file" : "plugins/org.apache.cordova.camera/www/CameraConstants.js",
        "id" : "org.apache.cordova.camera.Camera",
        "clobbers" : [ "Camera" ]
    },
    {
        "file" : "plugins/org.apache.cordova.camera/www/CameraPopoverOptions.js",
        "id" : "org.apache.cordova.camera.CameraPopoverOptions",
        "clobbers" : [ "CameraPopoverOptions" ]
    },
    {
        "file" : "plugins/org.apache.cordova.camera/www/Camera.js",
        "id" : "org.apache.cordova.camera.camera",
        "clobbers" : [ "navigator.camera" ]
    },
    {
        "file" : "plugins/org.apache.cordova.camera/www/CameraPopoverHandle.js",
        "id" : "org.apache.cordova.camera.CameraPopoverHandle",
        "clobbers" : [ "CameraPopoverHandle" ]
    },
    {
        "file" : "plugins/com.phonegap.plugins.barcodescanner/www/barcodescanner.js",
        "id" : "com.phonegap.plugins.barcodescanner.barcodescanner",
        "clobbers" : [ "barcodescanner" ]
    },
  { "file": "plugins/com.gldjc.guangcaiclient/www/gcapp.js", "id": "com.gldjc.guangcaiclient.gcapp", "clobbers": [ "gcapp" ] }
];
module.exports.metadata = 
// TOP OF METADATA
{
    "org.apache.cordova.device": "0.2.13"
}
// BOTTOM OF METADATA
});

file表示咱们去哪里找脚本插件定义js,id是以前咱们在gcapp.js中开头cordova.define中写的标识,cordova经过这个标志去找到咱们的Javascript插件定义,而clobbers则是咱们在前端经过什么对象名来调用这个插件。这里我写的是gcapp,则后面调用则只须要写成gcapp.checkUpdate 便可

插件的调用

万事俱备,只欠东风,大家能够开始看到结果了,若是从头到这里一步成功,那应该仍是蛮兴奋的事情吧。

具体前端页面如何设计我就不说了,个人页面效果就如本文最前面的图片,在js中我是这些调用version的,至于checkUpdate就是同样了,在按钮的click事件中调用 gcapp.checkUpdate(); 便可

$(document).on("PG_pageinit", function(event) {
    gcapp.version(function(version){
            $("#version").html(version);
    });
});

 

PhoneGap App开发 477842664 Cordova App实战开发2 

相关文章
相关标签/搜索