一、搭建环境

请参考《Cordova创建项目、编译、安装》

二、创建项目:

创建命令:cordova create [文件名] [包名]

~/Desktop/Cordova$ cordova create MyCordovaCamera com.cs.camera
Creating a new cordova project.
~/Desktop/Cordova$ ls
MyCordovaCamera  

三、在Cordova项目中添加Android平台

1、进入刚刚创建的Cordova项目

~/Desktop/Cordova$ cd MyCordovaCamera

2、在Cordova项目中添加Android平台

~/Desktop/Cordova/MyCordovaCamera$ cordova platform add android

以上是创建Cordova项目,用来测试我们开发的cordova插件用的。下面开始进行插件开发的步骤介绍。

四、安装plugman插件

~$ sudo npm install -g plugman

五、创建一个插件

创建命令:

plugman create --name [插件名] --plugin_id [插件ID] --plugin_version [插件版本号]

我们插件创建在cordova项目的上一级目录:

~/Desktop/Cordova/MyCordovaCamera$ cd ..
~/Desktop/Cordova$ plugman create --name CSCamera --plugin_id com.cs.camera --plugin_version 1.0.0
~/Desktop/Cordova$ ls
CSCamera  MyCordovaCamera 

下面是创建好的插件目录:
在这里插入图片描述创建完插件后,目录如上图所示,其src目录是空的。www目录里有一个CSCamera.js文件。配置文件plugin.xml也仅如下的配置信息:

<?xml version='1.0' encoding='utf-8'?>
<plugin id="com.cs.camera" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>CSCamera</name>
    <js-module name="CSCamera" src="www/CSCamera.js">
        <!--这里是调用插件时用的名字,这个target就是js代码调用原生代码的引用-->
        <clobbers target="cordova.plugins.CSCamera" />
    </js-module>
</plugin>

六、编写生成的插件中的安卓代码

1、打开插件目录CSCamera中的src目录,发现目录是空的,这里需要手动添加android目录。
2、然后在android目录里创建一个java文件,创建一个类继承CordovaPlugin。

上面两步可以通过以下命令来自动完成,推荐这样做,命令要在插件目录下执行:

plugman platform add --platform_name [platform]      // platform 只能写ios或者android
~/Desktop/Cordova/CSCamera$ plugman platform add --platform_name android

生成的Java文件CSCamera.java如下:

package com.cs.camera;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 *  这个类回显一个从javascript调用的字符串。 
 */
public class CSCamera extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("coolMethod")) {
            String message = args.getString(0);
            this.coolMethod(message, callbackContext);
            return true;
        }
        return false;
    }

    private void coolMethod(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}

插件的安卓代码已经完成了。
给插件添加完平台配置后,plugin.xml配置文件也随之增加了平台的配置信息:

<platform name="android">
    <config-file parent="/*" target="res/xml/config.xml">
    <!--name要与java类名一致都为CSCamera, param标签中的value是插件安装好后java类名全路径-->
    <feature name="CSCamera">
        <param name="android-package" value="com.cs.camera.CSCamera" />
    </feature>
    </config-file>
    <config-file parent="/*" target="AndroidManifest.xml">
    </config-file>
    <!--src为java源文件的路径,target-dir为插件安装好后的源文件的位置,要和上面的feature标签下param标签里的value中的包名对应-->
    <source-file src="src/android/CSCamera.java" target-dir="src/com/cs/camera" />
</platform>

七、配置plugin.xml

但是插件目前还没有办法识别到我们写的java类和java方法。因此,我们需要在plugin.xml文件对我们写的东西进行声明:

<?xml version='1.0' encoding='utf-8'?>
<!--id代表这个插件的唯一标识,在上传到npm后,用户都是通过这个插件id去下载的-->
<plugin id="com.cs.camera" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
   <!--插件名称-->
   <name>CSCamera</name>
   <!--配置JS的路径-->
   <!--文件中可能会有多个js-module的,一个js-module就是一个调用的方式,这里用户调用的方式就是cordova.plugins.CSCamera.方法名,如对外提供toast这个方法,那调用方式就为cordova.plugins.CSCamera.toast-->
   <!--js-module标签中的name要和www文件夹下CSCamera.js这个文件名一样-->
   <js-module name="CSCamera" src="www/CSCamera.js">
       <!--这里是调用插件时用的名字,这个target就是js代码调用原生代码的引用-->
       <clobbers target="cordova.plugins.CSCamera" />
   </js-module>
   <!--添加Android平台-->
   <platform name="android">
       <config-file target="AndroidManifest.xml" parent="/manifest">
           <!--配置权限-->
           <uses-permission android:name="android.permission.INTERNET"/>
           <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
           <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
       </config-file>
       <config-file target="AndroidManifest.xml" parent="application">
         <provider
             android:name="org.apache.cordova.camera.FileProvider"
             android:authorities="${applicationId}.provider"
             android:exported="false"
             android:grantUriPermissions="true" >
             <meta-data
                 android:name="android.support.FILE_PROVIDER_PATHS"
                 android:resource="@xml/camera_provider_paths"/>
         </provider>
       </config-file>
       <!--插件中src/android中的所有java文件都需要在这里声明,否则无法调用-->
       <!--src为java源文件的路径,target-dir为插件安装好后,源文件的位置,要和下面的feature标签下param标签里的value中的包名对应-->
       <source-file src="src/android/CSCamera.java" target-dir="src/com/cs/camera" />
        <!--插件的配置信息, build的时候会添加到res/xml/config.xml文件中-->
       <config-file parent="/*" target="res/xml/config.xml">
           <!--name要与java类名一致都为CSCamera, param标签中的value是插件安装好后java类名全路径-->
           <feature name="CSCamera">
               <!--插件入口-->
               <param name="android-package" value="com.cs.camera.CSCamera" />
           </feature>
       </config-file>
   </platform>
</plugin>

在android目录下创建xml目录:

~/Desktop/Cordova/CSCamera/src/android$ mkdir xml

创建camera_provider_paths.xml文件

~/Desktop/Cordova/CSCamera/src/android/xml$ touch camera_provider_paths.xml

文件内容为:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

这是为了解决在高版本的android系统中,不能再直接通过file://的方式来获取文件的问题。

八、编写CSCamera.js文件

这个js文件,在我们创建了插件后会自动生成:

var exec = require('cordova/exec');

exports.toast = function (arg0, success, error) {
    exec(success, error, 'CSCamera', 'coolMethod', [arg0]);
};

注意:

  • CSCamera:是plugin.xml中配置的feature的name
  • coolMethod是对应名为CSCamera的java类中的方法,这也是为什么要求feature的name的值要和java类名一致的原因。
  • toast:是在外部使用时调用的方法,对使用者是可见的。

九、修改CSCamera.java类

改动其实不是很多,就是加了Toast.makeText(cordova.getActivity(),“Hello world”,Toast.LENGTH_LONG).show()。如果我们成功调用了插件,那么就会打印这句话。

public class CSCamera extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("coolMethod")) {// 对应toastPlugin.js中exec方法的第4个参数
            String message = args.getString(0);
            Toast.makeText(cordova.getActivity(),"Hello world",Toast.LENGTH_LONG).show();
            this.coolMethod(message, callbackContext);
            return true;
        }

        return false;
    }

    private void coolMethod(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}

十、配置package.json

在package.json配置该插件信息,没有这个文件,我们添加插件时会出现错误!进入插件目录,执行 npm init:

~/Desktop/Cordova/CSCamera$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (CSCamera) CSCamera
Sorry, name can no longer contain capital letters.
name: (CSCamera) cscamera
version: (1.0.0) 
description: This is a camera plugin which will be provided the ability of take picture for H5 App.
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /home/kyun/Desktop/Cordova/CSCamera/package.json:

{
  "name": "cscamera",
  "version": "1.0.0",
  "description": "This is a camera plugin which will be provided the ability of take picture for H5 App.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Is this ok? (yes) 

初始化完成后,就会在插件的根目录下,生产一份package.json文件。

十一、安装插件到cordova项目

cordova plugin add [插件路径]    
cordova plugin remove [插件的包名]

以上两个命令都要在cordova项目的根目录执行。添加插件就是把我们做好的插件,添加到Android项目的assets目录中,因此

每次修改了插件内容的话都需要移除并重新添加。

安装插件:

~/Desktop/Cordova/CSCamera$ pwd
/home/kyun/Desktop/Cordova/CSCamera
~/Desktop/Cordova/CSCamera$ cd ..
~/Desktop/Cordova$ ls
CSCamera  MyCordova  MyCordovaCamera  sample
~/Desktop/Cordova$ cd MyCordovaCamera
~/Desktop/Cordova/MyCordovaCamera$ cordova plugin add /home/kyun/Desktop/Cordova/CSCamera
Installing "com.cs.camera" for android
Adding com.cs.camera to package.json

添加后,就会在MyCordovaCamera项目的插件目录里有这个插件:
在这里插入图片描述添加插件出现的错误,请参考《cordova项目添加插件出错CordovaError: Could not determine package name from output》
移除插件也很方便:

~/Desktop/Cordova/MyCordovaCamera$ cordova plugin remove com.cs.camera

当你反复进行上面两个操作时,可能会报错,小技巧:再保存一下plugin.xml文件,再来进行添加插件操作。

十二、调用插件

打开cordova项目,找到www/index.html, index.html是这个h5 App的入口,我们可以在里面测试我们的插件是否被调用:

<body>
        <div class="app">
            <h1>Apache Cordova</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
                <button id="test_plugin">测试插件</button>
            </div>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>

注意:尽量避免直接在HTML标签上注册事件,因为那可能会失败。在一些浏览器如chrome上,它会认为这是一种不安全的操作,于是乎,事件就会被屏蔽掉。推荐的做法是在js代码里注册事件。所以我们把上面“测试插件”按钮的事件放在js/index.js文件里注册:

document.getElementById('test_plugin').onclick = function(){
    cordova.plugins.CSCamera.toast("成功了",function(success){
		alert(success);
	},function(err){
		alert(err);
	});
};

编译cordova项目,然后安装测试。致此,自定义开发插件的基本过程就是这样大家可以试着做一下。
最快的安装测试方式:(1)用USB数据线连接手机和手提电脑;(2)把手机的调试模式打开;(3)在Cordova项目的根目录下,运行命令:

~/Desktop/Cordova/MyCordovaCamera$ cordova run android

这样Cordova项目在编译完成后,会直接在手机上运行起来。
注意不要打开其他模拟器和连接多台手机,否则你就要特别使用–target参数来指定运行在哪台设备上了。
查看连接到电脑上的设备:

~$ adb devices
List of devices attached
6cd18d00	device

指定运行设备:

~/Desktop/Cordova/MyCordovaCamera$ cordova run android --target 6cd18d00

不过,当只连了一台设备时,就会默认为这一台,不需要特别指定。

谢谢阅读。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐