Monacaアプリ、ひいてはCordovaアプリを開発していて避けては通れないのが、「Cordovaプラグイン」の存在です。
スマートフォンの機能(例えば、カメラのエフェクト、アプリ内課金など)を使おうと思った時、Web技術だけでは限界があります。そうした時にWeb技術とネイティブの橋渡しをしてくれるのが、「Cordovaプラグイン」になります。
「Cordovaプラグイン」は、すでに数千種類も作成されているので、大抵の場合はこの中から選べば十分でしょう。しかし、AndroidやiOSのバージョンアップによって動かなくなったり、新しい機能がまだプラグインがない場合もあります。そうした時に備え、自分でプラグインの作り方を学んでおくのは大事です。
この記事では、最も基礎的なプラグイン作成法を紹介します。
このプラグインでは、バッテリーの残量を取得するという処理を行っています。
基本形
まず最初にディレクトリを作成します。
1 |
$ mkdir my-cordova-plugin |
この中に package.json
と plugin.xml
というファイルを作成します。
さらに、 src
と www
というディレクトを作ります。
そして、 src
の中に android
、ios
というディレクトリを作成します。
構造は、次のようになります。
1 2 3 4 5 6 7 8 9 |
$ tree . ├── package.json ├── plugin.xml ├── src │ ├── android │ └── ios └── www |
package.json
と plugin.xml
は、Cordovaプラグインに必要な情報です。元々は plugin.xml
だけでしたが、最近は npm(Node.jsのパッケージ管理) でインストールできるようになったので、package.json
が追加されています。
src
は、ソースコードが入るディレクトリです。 androidはAndroid用、iosはiOS用のソースコードが入ります。
package.json について
例えば、package.json
は次のようになります。プラグインに関する説明が殆どです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ "version": "0.0.1", "name": "cordova-plugin-battery", "description": "Cordova Battery Plugin", "cordova": { "id": "cordova-plugin-battery", "platforms": [ "android", "ios" ] }, "keywords": [ "cordova", "battery", "cordova-android", "cordova-ios" ], "engines": [] } |
plugin.xmlについて
plugin.xml
では、各プラットフォーム(Android/iOS)ごとに設定を記述します。対象のファイルであったり、Androidであれば必要な権限を記述します。詳しくは、コメントを参考にしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?xml version="1.0" encoding="UTF-8"?> <!-- プラグインのIDを記述。バージョンをpackage.jsonと合わせておく --> <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="io.monaca.plugin.battery" version="0.0.1"> <!-- プラグイン全体に関する設定 --> <name>BatteryPlugin</name> <!-- プラグインの説明 --> <description>Battery Plugin</description> <!-- プラグイン作成者 --> <author>Atsushi Nakatsugawa</author> <!-- ライセンス --> <license>MIT License</license> <!-- 対応Cordovaのバージョン --> <engines> <engine name="cordova" version=">=3.5.0" /> </engines> <!-- アプリ側で呼び出すJavaScriptファイル名 --> <js-module src="www/battery.js" name="battery"> <clobbers target="Battery" /> </js-module> <!-- iOS用の設定 --> <platform name="ios"> <!-- config.xmlに対する設定があればここに記述 --> <config-file target="config.xml" parent="/*"> <feature name="CVBatteryPlugin"> <param name="ios-package" value="CVBatteryPlugin"/> </feature> </config-file> <!-- 対象のソースコード --> <source-file src="src/ios/CVBatteryPlugin.swift" target-dir="src/ios" /> </platform> <!-- Android用の設定 --> <platform name="android"> <!-- config.xmlに対する設定があればここに記述 --> <config-file target="res/xml/config.xml" parent="/*"> <feature name="CVBatteryPlugin"> <param name="android-package" value="io.monaca.plugin.CVBatteryPlugin"/> </feature> </config-file> <!-- AndroidManifest.xmlに対する設定があればここに記述 --> <!-- 主に権限に関する設定を記述します --> <config-file target="AndroidManifest.xml" parent="/*"> <uses-permission android:name="android.permission.BATTERY_STATS" /> </config-file> <!-- 対象のソースコード --> <source-file src="src/android/io/monaca/plugin/CVBatteryPlugin.java" target-dir="src/io/monaca/plugin" /> </platform> </plugin> |
iOS側のコード
iOSでは、 Swift が使えるようになったので、これまでのように .h/.m ファイルで分ける必要がなくなりました。今回の例のように、バッテリー残量を取る場合、次のようなコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import Foundation import UIKit @objc(CVBatteryPlugin) class CVBatteryPlugin: CDVPlugin { // JavaScriptに公開する関数名を記述 @objc(status:) func status(command: CDVInvokedUrlCommand) { // バッテリーの残量を取得 UIDevice.current.isBatteryMonitoringEnabled = true let bLevel:Float = UIDevice.current.batteryLevel // 返却するレスポンスを作成 let result = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: String(bLevel)) // コールバック形式でレスポンスを返却 self.commandDelegate!.send(result, callbackId: command.callbackId) } } |
Android側のコード
Androidでは、従来通り Java を使います。工夫すると Kotlin が使えるようですが、 Java を使う方が簡単でしょう。
Javaの場合、 src/android/io/monaca/plugin/CVBatteryPlugin.java
といった具合にディレクトリを作成してコードを置くのが基本になるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package io.monaca.plugin; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; import android.content.IntentFilter; import android.content.Intent; import android.os.BatteryManager; import android.content.Context; public class CVBatteryPlugin extends CordovaPlugin { // Androidは必ずexecuteが呼び出されます @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { // actionにJavaScriptで呼び出したメソッド名が入るので、必要に応じて処理分岐します IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); // バッテリーの残量の取得 Context context = this.cordova.getActivity().getApplicationContext(); Intent batteryStatus = context.registerReceiver(null, ifilter); int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float bLevel = level / (float)scale; // コールバック形式でレスポンスを返却 callbackContext.success(String.valueOf(bLevel)); return true; } } |
JavaScriptについて
アプリから呼び出すJavaScriptは、 www/battery.js
として作成します。これは plugin.xml
で指定したパスになります。 cordova.exec
を使うのは基本ですが、その呼び出し方は自由です。例えば、以下はコールバック形式での例です。
1 2 3 4 5 6 7 8 |
const Battery = function() {}; Battery.prototype.status = function(success, fail, args) { cordova.exec(success, fail, "CVBatteryPlugin","status", args); }; const battery = new Battery(); module.exports = battery; |
アプリから呼び出す際には、次のようになるでしょう。
1 |
Battery.status(level => {/* バッテリーの残量*/}, err => { /* エラー */ }) |
使い方について
Cordovaプラグインができあがったら、Cordovaプラグインの管理からアップロードします。

方法としては、2つあります。
- プラグイン全体をZip圧縮
- アップロードしたファイルのURLを指定
後は、Monaca上でアプリをビルドすれば使えるようになります。
テストについて
開発時のテストは、ローカルコンピュータにCordovaコマンドをインストールし、ローカルで実行しながら行うのがいいでしょう。その場合、XcodeやAndroid Studioのブレークポイントが利用できます。

まとめ
自分でCordovaプラグインを作るか否かに関わらず、仕組みを知っておけば、動作を掘り下げて調べる時にも役立ちます。ネイティブの言語を知る必要はありますが、小さなプラグインであれば、コードリーディングもそれほど大変ではないはずです。
プラグインを使うことで、皆さんのアプリがより魅力的になるでしょう。ぜひプラグイン開発にもトライしてみてください。