cordova应用如果需要调用原生安卓接口,方法是使用cordova插件,cordova官方提供了主流原生功能的插件,但如果还不能满足需求,也可以自己开发cordova插件

 

以下介绍开发一个最简单的插件,功能是调用原生的toast弹出信息

 

首先先用as创建新工程,用于编写插件的代码

PS:开发cordova插件其中一个坑是没有一个好的编写代码环境,甚至插件的所有类文件都要手动添加到配置文件,这点后面会有体验

 

项目名叫plug1,包(package)名要倒着写

Android 直接以来本地插件工程 安卓插件开发_json

Android 直接以来本地插件工程 安卓插件开发_Android 直接以来本地插件工程_02

默认添加empry activity

Android 直接以来本地插件工程 安卓插件开发_java_03

Android 直接以来本地插件工程 安卓插件开发_移动开发_04

配置完成后等待一段时间,待进度条消失后,build一下,没报错就说明成功

 

建名为org.apache.cordova的包,步骤如下:

Android 直接以来本地插件工程 安卓插件开发_json_05

Android 直接以来本地插件工程 安卓插件开发_Android 直接以来本地插件工程_06

Android 直接以来本地插件工程 安卓插件开发_json_07

Android 直接以来本地插件工程 安卓插件开发_android_08

 

回到capp1,可以看到有org.apache.cordova包,把此包下所有文件,拷到上一步新建的包,目的是让plug1拥有cordova的类(使得可以开发cordova插件)

Android 直接以来本地插件工程 安卓插件开发_移动开发_09

 

拷后效果图

Android 直接以来本地插件工程 安卓插件开发_移动开发_10

用于开发cordova插件时编码的plug1项目到此建立完成,后续如果还有多个插件开发都可以重用此项目

此项目不是必须的(因为最终编译不在此),理论上可以用记事本来编码

 

然后开始插件的编码,首先新建包com.cesc.ewater.cordovaPlugin

Android 直接以来本地插件工程 安卓插件开发_json_11

 

新建类ToastPlugin,此类内容在下面有提供,可以直接拷进去

package com.cesc.ewater.cordovaPlugin;
 
import android.widget.Toast;
 
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
 
/**
 * Toast插件
 */
public class ToastPlugin extends CordovaPlugin {
    @Override
    public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
        return super.execute(action, rawArgs, callbackContext);
    }
 
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        return super.execute(action, args, callbackContext);
    }
 
    /**
     * js调用插件方法后,会进入到此方法
     *
     * @param action          插件的方法名,如果一个插件有多个方法,通过此值区分
     * @param args            js传入的参数,用于插件外给插件传值,数组类型,可以传入多个参数
     * @param callbackContext The callback context used when calling back into JavaScript.
     * @return 插件是否正常执行,bool类型。还会影响到js调用的回调,如果是true就执行success的回调,false执行fail的回调
     * @throws JSONException
     */
    @Override
    public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
        //通过action判断调用哪个方法
        if (action.equals("showToast")) {
            //这里可以实现一些你的原生逻辑功能
            //args.getString(0)意思是读取第1个传入参数,且类型是string
            Toast.makeText(cordova.getActivity(), args.getString(0), Toast.LENGTH_SHORT).show();
 
            //插件给外部js返回值的实现,PluginResult构造函数参数1代表执行结果状态,参数2是返回的值
            PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, "插件返回的值");
            pluginResult.setKeepCallback(true);
            callbackContext.sendPluginResult(pluginResult);
            return true;
        }
        return false;
    }
}

最终效果

Android 直接以来本地插件工程 安卓插件开发_android_12

 

然后回到capp1

 

首先用npm安装plugman(全局安装),命令如下:npm install -g plugman,在此没有截图

PS:只要在第一次使用安装

 

命令行进入capp1目录,执行以下命令创建插件,插件命名为toast-plugin

plugman create --name toast-plugin --plugin_id toast-plugin --plugin_version 1.0.0

PS:其中—name后面是插件名,--plugin_id后面是插件id,--plugin_version后面是版本

 

成功后生成此目录

Android 直接以来本地插件工程 安卓插件开发_移动开发_13

 

在此目录下,新建文件夹android

Android 直接以来本地插件工程 安卓插件开发_移动开发_14

 

把刚才在plug1编辑的ToastPlugin类文件拷到android文件夹里

Android 直接以来本地插件工程 安卓插件开发_java_15

PS:原则上要把此插件所有的文件都放到此目录,此例只拷一个文件因为此例的插件确实只有一个类文件,非常简单

PS:此目录下的文件的目录结构不需要跟包匹配,所有文件都放根目录都可以,因为后面还会有配置文件配置类文件和包名

 

然后开始编辑plugin.xml

Android 直接以来本地插件工程 安卓插件开发_Android 直接以来本地插件工程_16

修改成以下的内容(提供全文内容可以直接复制)

<?xml version='1.0' encoding='utf-8'?>
<plugin id="toast-plugin" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <!--插件名-->
       <name>toast-plugin</name>
       <!--js部分配置-->
    <js-module name="ToastPlugin" src="www/toast-plugin.js">
              <!--js调用的对象名-->
        <clobbers target="ToastPlugin" />
    </js-module>
      
       <!--添加安卓平台-->
    <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*"> 
                     <!--js调用的对象名-->
            <feature name="ToastPlugin">
                            <!-- value=java类名全路径-->
                <param name="android-package" value="com.cesc.ewater.cordovaPlugin.ToastPlugin"/>
            </feature> 
        </config-file> 
              <!-- src:java源文件的路径, target-dir:插件安装好后,源文件的位置,要和上面的包名对应 -->
        <source-file src="src/android/ToastPlugin.java" target-dir="src/com/cesc/ewater/cordovaPlugin" />         
    </platform>
</plugin>

PS:此文件的详细说明,也可以先跳过不看

 

此文件是插件注入js的对象,根目录在插件目录

Android 直接以来本地插件工程 安卓插件开发_java_17

 

这几个都是js调用插件的对象名,应该是一样的

Android 直接以来本地插件工程 安卓插件开发_json_18

 

插件所有的文件(包括类文件,layout的xml文件,引用的jar包文件等等)都要配置到此

Android 直接以来本地插件工程 安卓插件开发_移动开发_19

plugin.xml说明到此为止

 

然后开始编辑此文件

Android 直接以来本地插件工程 安卓插件开发_json_20

内容如下,可以直接复制进去,

var exec = require('cordova/exec');
 
//一个exports.XXX代表插件的一个方法,exports后面和exec方法的参数4都是方法名称(此例都是showToast)
var exec = require('cordova/exec');
 
//一个exports.XXX代表插件的一个方法,exports后面和exec方法的参数4都是方法名称(此例都是showToast)
exports.showToast = function (arg0, success, error) {
       //参数1和参数2分别是调用插件成功和失败的回调方法(js)
       //参数3是插件名
       //参数4是方法名
       //参数5是js的传参
    exec(success, error, 'ToastPlugin', 'showToast', [arg0]);
};

打开控制台,进入插件目录,执行npm init

Android 直接以来本地插件工程 安卓插件开发_android_21

 中间有很多输入项,直接回车即可,成功的效果

Android 直接以来本地插件工程 安卓插件开发_Android 直接以来本地插件工程_22

 

完成后插件目录多了个package.json文件,开始编辑他

 

添加此部分,下面有文本内容

PS:id是插件名称

Android 直接以来本地插件工程 安卓插件开发_android_23

"cordova": {
    "id": "toast-plugin",
    "platforms": [
      "android"
    ]
  },

插件修改到此结束,开始把插件添加到cordova应用

 

控制台进入capp1的安卓平台目录,输入以下命令cordova plugin add E:\project\201712cordovaTest\code\capp1\toast-plugin,命令中的路径是插件的目录

PS:此命令意思是把某个目录的插件添加capp1的cordova应用

Android 直接以来本地插件工程 安卓插件开发_json_24

成功的效果

Android 直接以来本地插件工程 安卓插件开发_java_25

成功后capp1会多了如下文件,可以见到插件的ToastPlugin.java类文件

Android 直接以来本地插件工程 安卓插件开发_android_26

 

到此完成添加插件到cordova应用

 

接下来开始修改h5应用代码,在h5应用中使用js调用插件

 

打开已经被遗忘的vue1

找到主页的js文件

Android 直接以来本地插件工程 安卓插件开发_移动开发_27

添加代码:ToastPlugin.showToast("hello world");

意思是调用名称为ToastPlugin的插件的showToast方法,并传入参数”hello world”

Android 直接以来本地插件工程 安卓插件开发_json_28

 

修改代码完毕,npm build一下

PS:从这段操作开始,在之前的 使用cordova把h5应用打包成apk 已经有说明,也就是h5应用修改后,通过一系列操作把他打包成apk,但在此也重复说明一次

Android 直接以来本地插件工程 安卓插件开发_android_29

 

打开www(用webstrom打开,之前有说过),把刚才生成的文件拷过去

PS:注意每次build生成的文件都会有一堆随机数,如果随机数变了就说明该文件内容有修改所以重新生成,反之就没变

Android 直接以来本地插件工程 安卓插件开发_android_30

 

然后修改indel.html文件里引用文件的文件名

Android 直接以来本地插件工程 安卓插件开发_android_31

 

然后开始cordova打包apk,命令行进入capp1的目录,运行命令cordova build android

Android 直接以来本地插件工程 安卓插件开发_android_32

build成功后,回到capp1,插上手机,开始调试

 

成功的话,点击左上角的【功能1】按钮,会弹出消息“hello world”

Android 直接以来本地插件工程 安卓插件开发_移动开发_33

 

追加小章节:

插件修改后如何使修改生效:

假设把弹出的文本内容加上123

Android 直接以来本地插件工程 安卓插件开发_android_34

 

代码修改完后,控制台进入capp1目录,执行命令:cordova plugin rm toast-plugin,意思是删除插件

Android 直接以来本地插件工程 安卓插件开发_Android 直接以来本地插件工程_35

 

然后再执行添加插件的命令

Android 直接以来本地插件工程 安卓插件开发_移动开发_36

成功后,在capp1的as build一下,再运行可看到修改后的效果

 

PS:虽然有插件更新的命令cordova plugin update xxx,然而使用过发现无效,因此只能删除再添加