ionic(cordova)のカスタムプラグイン開発のワークフローを構築する
カスタムプラグイン開発のワークフローが必要だ!
ionic(cordova)のカスタムプラグインを開発するのはそれほど難しいことではない。しかし当然の事ながら、プラグインの開発は試行錯誤を重ねる必要がある。そのための円滑なワークフローを構築するのにかなり苦労したので、まとめておきたいと思う。
ここでは、ionic側からカスタムプラグインを叩いてネイティブのノーティフィケーションを表示するサンプルを作ろうと思う。とりあえずAndroid用を開発することにする。
ionicプロジェクトの作成
まず、ionicプロジェクトを作り、CordovaLib-debug.aarを作るため一度ビルドする。
AndroidStudioプロジェクトの作成
AndroidStudioで~/Documents/git/customplugin-androidに、パッケージ名ex.customplugin、Blank Activityを選択してプロジェクトを作る。
そして、このようなレイアウトを作る。
CordovaLib-debug.aarを組み込む。これはAndroidStudioでCordova関連クラスをimportするのに必要。
File>New>New module>Import .JAR or .ARR Packege>Next。
File Name: ~/Documents/git/customplugin/platforms/android/CordovaLib/build/outputs/aar/CordovaLib-debug.aar
からのFinish。
左のツリーでGradle Scripts>build.gradle(Module app)を開き、dependency部にCordovaLib-debugの記述を追加。
ここでCordova関連クラスをimportできるようにするために一度ビルド。Build>Rebuild Project。
ノーティフィケーションアイコンの作成
適当なサイズのアイコン画像(512x512程度、アルファ付き、塗りは白、アイコン内のパディングは極力少なく)を用意する。
その画像をこちらにアップロードしてDownload Zip。
Android Asset Studio - Icon Generator - Notification icons
ダウンロードしたic_stat_notif_icon.zipを解凍するとresフォルダができるので、その配下のフォルダを全てcustomplugin-android/app/src/main/resにコピー。
これでカスタムプラグインを作る用意ができた。
カスタムプラグインの開発(ネイティブ側)
File>New>Java Class>Name: CustomPlugin。
CustomPlugin.javaをこのように編集する。
MainActivity.javaをこのように編集する。
カスタムプラグインをネイティブで実行確認
Ctrl+Rで実行。
ボタンをクリックするとこのようにノーティフィケーションが表示された。
これでネイティブ側でのカスタムプラグイン開発は終了。ここからが本番。
ionicプロジェクトにカスタムプラグインを構築するフォルダを作成
ここではcustomplugin/plugins-custom/ex.custompluginとする。pluginsというフォルダが元からあるが、ここに作ってはいけない。pluginsはionicのシステムにマネージメントさせる。
ライブラリ(jar)をコピー
次にプラグインに必要なライブラリ(jar)をコピーしておく。
プラグインJSを作成
plugins-custom/ex.customplugin/customplugin.jsをこのように編集する。これがネイティブとの橋渡し役をする。
plugin.xmlを作成
plugins-custom/ex.customplugin/plugin.xmlをこのように編集する。
開発中のプラグインを素早くionicに反映させるgulpスクリプトの作成
次に、開発・編集したネイティブカスタムプラグインをionicプロジェクトへ素早く反映させるためのgulpスクリプトを書く。
まず必要なnodeモジュールをプロジェクトにインストールする。
ところで、ionicはビルド時にprepareを行うが、これはplatform配下に様々なファイルをコピーしたりする処理だ。hooks/after_prepare/010_add_platform_class.jsはそのprepare後に行われる処理。
カスタムプラグイン関連の処理はこのprepareの前に行わなければならないので、スクリプトをhooks/before_prepare/010_copy_custom_plugins.jsと作成してこのように編集する。
gulpスクリプトの動作確認
ここで「ionic prepare android」して次の項目を確認する。
これでAndroidStudioで編集したカスタムプラグインのソースをプラグインの追加と削除をせずとも即座に、また自動的にionicプロジェクトに反映させることができるようになった。
カスタムプラグインのインストール
ついにionicプロジェクトにカスタムプラグインをインストールするが、その前にplatforms/android/src/ex/customplugin/CustomPlugin.javaが存在するとインストール時にエラーになるので削除しておく。
そして「ionic plugin add plugins-custom/ex.customplugin/」でインストール。次の項目を確認する。
asssets配下のcustomplugin.jsはprepare・ビルド時にplugins/ex.customplugin/customplugin.jsが毎回上書きコピーされる。before_prepareでplugins-custom配下のjs(マスター)をplugins配下にコピーしているのはそのためなので、編集はplugins-cutom配下のものを編集する。
java/jarファイルのコピーとplugin.xmlの設定によるconfig.xmlの変更はプラグインをインストールした時にしか行われない。jarの追加やplugin.xmlの変更は比較的少ないのでまぁそれでも良いが、javaファイルの変更は頻繁に行われるはずで、それではまずい。before_prepareでjavaファイルのコピーをしているのはこのため。
カスタムプラグインのアンインストール
ここで一度「ionic plugin rm ex.customplugin」でアンインストールして次の項目を確認する。
カスタムプラグインの再インストールスクリプトを作成
plugin.xmlの編集やjava/jarファイルの追加などを行う場合にはプラグインのインストール・アンインストールを繰り返すことになるので、このようなスクリプトを用意しておく。
「chmod 744 reinstall-custom-plugins.sh 」で実行権限を与えておくのを忘れずに。
カスタムプラグインをionicで動作確認
これでカスタムプラグインの導入は完了!最後にionicプロジェクトでの動作確認をする。
www/index.htmlをこのように編集する。
www/js/app.jsをこのように編集する。
「ionic run android」でAndroidの実機で実行。するとこのように表示される。
「ノーティフィケーション表示」のボタンをクリックすると、このようにノーティフィケーションが表示される。
つまり、ネイティブアプリケーションと同様に、カスタムプラグインを使ってionicからノーティフィケーションを表示できるようになったわけだ。
ワークフローの再確認
ここで安心してはいけない。目的はあくまでワークフローの構築。カスタムプラグインを変更して素早くionicのプロジェクトに反映させられるかを確認しなくてはならない。
AndroidStudioに戻り、CustomPlugin.javaのshowNotification()メソッドの1行目に「Toast.makeText(context, "ノーティフィケーション表示", Toast.LENGTH_LONG).show();
」を追加してネイティブのトーストを表示してみよう。実行するとこのようになる。
さて、ionicでも同様に動作するだろうか?「ionic run android」で実行。するとこのようになる。
このように、カスタムプラグインのJavaソースを変更してネイティブで動作を確認しつつ、その後にコマンド一発でionicでも動作を確認できるようになったわけだ。
各プロジェクトのダウンロード
いや〜大変(^^);
customplugin(ionicプロジェクト)とcustomplugin-android(AndroidStudioプロジェクト)はgithubにアップしてある。
junkoro/customplugin
junkoro/customplugin-android
ionic(cordova)のカスタムプラグインを開発するのはそれほど難しいことではない。しかし当然の事ながら、プラグインの開発は試行錯誤を重ねる必要がある。そのための円滑なワークフローを構築するのにかなり苦労したので、まとめておきたいと思う。
ここでは、ionic側からカスタムプラグインを叩いてネイティブのノーティフィケーションを表示するサンプルを作ろうと思う。とりあえずAndroid用を開発することにする。
ionicプロジェクトの作成
まず、ionicプロジェクトを作り、CordovaLib-debug.aarを作るため一度ビルドする。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cd ~/Documents/git/ | |
ionic start --id "ex.customplugin" customplugin blank | |
cd customplugin | |
ionic platform rm ios | |
ionic platform add android | |
ionic build android |
AndroidStudioプロジェクトの作成
AndroidStudioで~/Documents/git/customplugin-androidに、パッケージ名ex.customplugin、Blank Activityを選択してプロジェクトを作る。
そして、このようなレイアウトを作る。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<RelativeLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:paddingLeft="@dimen/activity_horizontal_margin" | |
android:paddingRight="@dimen/activity_horizontal_margin" | |
android:paddingTop="@dimen/activity_vertical_margin" | |
android:paddingBottom="@dimen/activity_vertical_margin" | |
tools:context=".MainActivity" | |
android:gravity="center_horizontal"> | |
<Button | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="ノーティフィケーション表示" | |
android:id="@+id/btnShow" /> | |
</RelativeLayout> |
CordovaLib-debug.aarを組み込む。これはAndroidStudioでCordova関連クラスをimportするのに必要。
File>New>New module>Import .JAR or .ARR Packege>Next。
File Name: ~/Documents/git/customplugin/platforms/android/CordovaLib/build/outputs/aar/CordovaLib-debug.aar
からのFinish。
左のツリーでGradle Scripts>build.gradle(Module app)を開き、dependency部にCordovaLib-debugの記述を追加。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
compile fileTree(dir: 'libs', include: ['*.jar']) | |
compile 'com.android.support:appcompat-v7:22.1.1' | |
compile project(':CordovaLib-debug') | |
} |
ここでCordova関連クラスをimportできるようにするために一度ビルド。Build>Rebuild Project。
ノーティフィケーションアイコンの作成
適当なサイズのアイコン画像(512x512程度、アルファ付き、塗りは白、アイコン内のパディングは極力少なく)を用意する。
その画像をこちらにアップロードしてDownload Zip。
Android Asset Studio - Icon Generator - Notification icons
ダウンロードしたic_stat_notif_icon.zipを解凍するとresフォルダができるので、その配下のフォルダを全てcustomplugin-android/app/src/main/resにコピー。
これでカスタムプラグインを作る用意ができた。
カスタムプラグインの開発(ネイティブ側)
File>New>Java Class>Name: CustomPlugin。
CustomPlugin.javaをこのように編集する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ex.customplugin; | |
import android.app.Notification; | |
import android.app.NotificationManager; | |
import android.content.Context; | |
import android.support.v4.app.NotificationCompat; | |
import android.util.Log; | |
import org.apache.cordova.CallbackContext; | |
import org.apache.cordova.CordovaInterface; | |
import org.apache.cordova.CordovaPlugin; | |
import org.apache.cordova.CordovaWebView; | |
import org.json.JSONArray; | |
import org.json.JSONException; | |
/** | |
* Cordovaカスタムプラグイン | |
*/ | |
public class CustomPlugin extends CordovaPlugin { | |
private Context context; | |
public static final String CMD_SHOW_NOTIFICATION = "showNotification"; | |
/** | |
* コンストラクタ(プラグイン時) | |
*/ | |
public CustomPlugin() { | |
} | |
/** | |
* コンストラクタ(非プラグイン時) | |
*/ | |
public CustomPlugin(Context context) { | |
this.context = context; | |
init(); | |
} | |
/** | |
* Cordovaプラグインとして動作するときの初期化処理 | |
* | |
* @param cordova | |
* @param webView | |
*/ | |
@Override | |
public void initialize(CordovaInterface cordova, CordovaWebView webView) { | |
super.initialize(cordova, webView); | |
context = cordova.getActivity(); | |
init(); | |
} | |
/** | |
* 初期化 | |
*/ | |
private void init() { | |
Log.i(null, "カスタムプラグイン初期化"); | |
} | |
/** | |
* cordovaプラグインの実行 | |
* | |
* @param action | |
* @param args | |
* @param callbackContext | |
* @return | |
* @throws JSONException | |
*/ | |
@Override | |
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { | |
Log.i(null, "カスタムプラグイン実行 action=" + action); | |
String msg = "対応コマンドがありません"; | |
if (action.equals(CMD_SHOW_NOTIFICATION)) { | |
String title = "タイトル"; | |
if (args.length() > 0) { | |
title = args.getString(0); | |
} | |
String text = "テキスト"; | |
if (args.length() >=1) { | |
text = args.getString(1); | |
} | |
showNotification(title, text); | |
} else { | |
if (callbackContext != null) { | |
callbackContext.error(msg); | |
} | |
Log.w(null, msg); | |
return false; | |
} | |
if (callbackContext != null) { | |
callbackContext.success(); | |
} | |
return true; | |
} | |
/** | |
* ノーティフィケーション表示 | |
* | |
* @param title | |
* @param text | |
*/ | |
private void showNotification(String title, String text) { | |
Log.i(null, "ノーティフィケーション表示 title=" + title + " text=" + text); | |
int NOTIF_ID = 1234; | |
Notification notif = new NotificationCompat.Builder(context) | |
.setSmallIcon(R.drawable.ic_stat_notif_icon) | |
.setAutoCancel(true) | |
.setContentTitle(title) | |
.setContentText(text) | |
.build(); | |
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); | |
nm.notify(NOTIF_ID, notif); | |
} | |
} //END class |
MainActivity.javaをこのように編集する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ex.customplugin; | |
import android.support.v7.app.ActionBarActivity; | |
import android.os.Bundle; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.widget.Button; | |
import org.json.JSONArray; | |
import org.json.JSONException; | |
public class MainActivity extends ActionBarActivity implements View.OnClickListener { | |
Button btnShow; | |
CustomPlugin plugin; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
btnShow = (Button)findViewById(R.id.btnShow); | |
btnShow.setOnClickListener(this); | |
plugin = new CustomPlugin(this); | |
} | |
@Override public void onClick(View v) { | |
try { | |
switch (v.getId()) { | |
case R.id.btnShow: | |
JSONArray ja = new JSONArray(); | |
ja.put("ネイティブでノーティフィケーション"); | |
ja.put("表示されるかな?"); | |
plugin.execute(CustomPlugin.CMD_SHOW_NOTIFICATION, ja, null); | |
break; | |
} | |
} catch (JSONException e) { | |
e.printStackTrace(); | |
} | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
// Inflate the menu; this adds items to the action bar if it is present. | |
getMenuInflater().inflate(R.menu.menu_main, menu); | |
return true; | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
// Handle action bar item clicks here. The action bar will | |
// automatically handle clicks on the Home/Up button, so long | |
// as you specify a parent activity in AndroidManifest.xml. | |
int id = item.getItemId(); | |
//noinspection SimplifiableIfStatement | |
if (id == R.id.action_settings) { | |
return true; | |
} | |
return super.onOptionsItemSelected(item); | |
} | |
} |
カスタムプラグインをネイティブで実行確認
Ctrl+Rで実行。
ボタンをクリックするとこのようにノーティフィケーションが表示された。
これでネイティブ側でのカスタムプラグイン開発は終了。ここからが本番。
ionicプロジェクトにカスタムプラグインを構築するフォルダを作成
ここではcustomplugin/plugins-custom/ex.custompluginとする。pluginsというフォルダが元からあるが、ここに作ってはいけない。pluginsはionicのシステムにマネージメントさせる。
ライブラリ(jar)をコピー
次にプラグインに必要なライブラリ(jar)をコピーしておく。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mkdir -p plugins-custom/ex.customplugin/libs/android | |
cp ~/Library/Android/sdk/extras/android/support/v7/appcompat/libs/android-support-v* plugins-custom/ex.customplugin/libs/android |
プラグインJSを作成
plugins-custom/ex.customplugin/customplugin.jsをこのように編集する。これがネイティブとの橋渡し役をする。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var exec = require('cordova/exec'); | |
var customplugin = { | |
showNotification: function(title, text) { | |
exec(null, null, 'customplugin', 'showNotification', [title, text]); | |
} | |
}; | |
module.exports = customplugin; |
plugin.xmlを作成
plugins-custom/ex.customplugin/plugin.xmlをこのように編集する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!-- | |
Apache Cordova API Documentation | |
https://cordova.apache.org/docs/en/5.0.0/plugin_ref_spec.md.html#Plugin%20Specification | |
このファイルを変更後は | |
「ionic plugin rm ex.customplugin」と | |
「ionic plugin add plugins-custom/ex.customplugin」の | |
併用でプラグインを更新しないとシステムが壊れる | |
--> | |
<!-- idはpluginsにコピーされる時のフォルダ名になる --> | |
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" | |
id="ex.customplugin" | |
version="0.1"> | |
<name>カスタムプラグイン</name> | |
<description>カスタムプラグイン</description> | |
<engines> | |
<engine name="cordova-android" version=">=4.0.0" /> | |
</engines> | |
<js-module src="customplugin.js"> | |
<!-- customplugin.js内でmodule.exportsしたパラメーター名を使う --> | |
<clobbers target="navigator.customplugin" /> | |
</js-module> | |
<!-- android --> | |
<platform name="android"> | |
<!-- プラグイン追加・削除時にplatfom/android/res/xml/config.xmlに下記の設定を追加・削除する --> | |
<config-file target="res/xml/config.xml" parent="/*"> | |
<!-- customplugin.js内のexecの第3引数と対応する --> | |
<feature name="customplugin"> | |
<!-- CustomPlugin.javaのパッケージ名を指定 --> | |
<param name="android-package" value="ex.customplugin.CustomPlugin"/> | |
</feature> | |
</config-file> | |
<!-- プラグイン追加・削除時にplatfom/android/libsに次のライブラリを追加・削除する --> | |
<source-file src="libs/android/android-support-v4.jar" target-dir="libs" /> | |
<source-file src="libs/android/android-support-v7-appcompat.jar" target-dir="libs" /> | |
<!-- プラグイン追加・削除時にplatfom/android/src/ex/custompluginに次のJavaソースファイルを追加・削除する --> | |
<source-file src="src/android/CustomPlugin.java" target-dir="src/ex/customplugin" /> | |
</platform> | |
</plugin> |
開発中のプラグインを素早くionicに反映させるgulpスクリプトの作成
次に、開発・編集したネイティブカスタムプラグインをionicプロジェクトへ素早く反映させるためのgulpスクリプトを書く。
まず必要なnodeモジュールをプロジェクトにインストールする。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ionicの場合gulpは標準なので必要無し | |
#npm install gulp --save | |
npm install del --save |
ところで、ionicはビルド時にprepareを行うが、これはplatform配下に様々なファイルをコピーしたりする処理だ。hooks/after_prepare/010_add_platform_class.jsはそのprepare後に行われる処理。
カスタムプラグイン関連の処理はこのprepareの前に行わなければならないので、スクリプトをhooks/before_prepare/010_copy_custom_plugins.jsと作成してこのように編集する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
'use strict'; | |
var gulp = require('gulp'); | |
var del = require('del'); | |
console.log('\n---- copy_custom_plugins START\n'); | |
var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []); | |
//console.log('platforms.length=' + platforms.length); | |
var customPluginName = 'ex.customplugin'; | |
var customPluginSrc = 'plugins-custom/' + customPluginName; | |
var customPluginDst = 'plugins/' + customPluginName; | |
for (var x = 0; x < platforms.length; x++) { | |
try { | |
var platform = platforms[x].trim().toLowerCase(); | |
var platformRoot = 'platforms/' + platform; | |
var pluginSrcRoot = '../customplugin-' + platform; | |
//Android | |
if (platform == 'android') { | |
console.log('Android用処理開始'); | |
//customPluginSrcのJavaをクリーンしつつ、プラグインプロジェクトからJavaをコピー | |
var customPluginPackage = 'ex/customplugin'; | |
var javaSrcRoot = pluginSrcRoot + '/app/src/main/java/' + customPluginPackage; | |
var javaSrc = [javaSrcRoot + '/*.java', '!' + javaSrcRoot + '/MainActivity.java']; | |
var customPluginSrcAndroid = customPluginSrc + '/src/android'; | |
del.sync(customPluginSrcAndroid + '/*.java'); | |
gulp.src(javaSrc).pipe(gulp.dest(customPluginSrcAndroid)); | |
//platforms/android配下のJavaソースをクリーン | |
var javaDstRoot = platformRoot + '/src/' + customPluginPackage; | |
del.sync([javaDstRoot + '/*.java', '!' + javaDstRoot + '/MainActivity.java']); | |
//プラグインプロジェクトからplatforms/android配下に直接Javaをコピー | |
gulp.src(javaSrc).pipe(gulp.dest(javaDstRoot)); | |
//プラグインプロジェクトからplatforms/android配下に直接リソースをコピー | |
var resSrcRoot = pluginSrcRoot + '/app/src/main/res'; | |
var resDstRoot = platformRoot + '/res'; | |
gulp.src(resSrcRoot + '/**/ic_stat_notif_icon.png').pipe(gulp.dest(resDstRoot)); | |
//JSはcustomPluginSrcがマスターなのでコピー | |
gulp.src(customPluginSrc + '/*.js').pipe(gulp.dest(customPluginDst)); | |
//その他のファイルは | |
//「ionic plugin rm customPluginName」と | |
//「ionic plugin add plugins-custom/ustomPluginName」の | |
//併用で自動的にコピーさせないとシステムが壊れるのでコピーしない | |
//その他のファイルの変更時はreinstall-custom-plugins.shで行うこと | |
} | |
} catch(e) { | |
process.stdout.write(e); | |
} | |
} //END for | |
console.log('\n---- copy_custom_plugins END\n'); |
gulpスクリプトの動作確認
ここで「ionic prepare android」して次の項目を確認する。
- plugins-custom/ex.customplugin/src/android/CustomPlugin.javaが存在するか?
- platforms/android/src/ex/customplugin/CustomPlugin.javaが存在するか?
- platforms/android/res/drawable-hdpi-v11/ic_stat_notif_icon.pngなどのリソースが存在するか?
これでAndroidStudioで編集したカスタムプラグインのソースをプラグインの追加と削除をせずとも即座に、また自動的にionicプロジェクトに反映させることができるようになった。
カスタムプラグインのインストール
ついにionicプロジェクトにカスタムプラグインをインストールするが、その前にplatforms/android/src/ex/customplugin/CustomPlugin.javaが存在するとインストール時にエラーになるので削除しておく。
そして「ionic plugin add plugins-custom/ex.customplugin/」でインストール。次の項目を確認する。
- platforms/android/assets/www/plugins/ex.customplugin/customplugin.jsが存在するか?
- platforms/android/libs/配下にandroid-support-v4.jarとandroid-support-v7-appcompat.jarは存在するか?
- platforms/android/res/xml/config.xml内に「ex.customplugin.CustomPlugin」が存在するか?
asssets配下のcustomplugin.jsはprepare・ビルド時にplugins/ex.customplugin/customplugin.jsが毎回上書きコピーされる。before_prepareでplugins-custom配下のjs(マスター)をplugins配下にコピーしているのはそのためなので、編集はplugins-cutom配下のものを編集する。
java/jarファイルのコピーとplugin.xmlの設定によるconfig.xmlの変更はプラグインをインストールした時にしか行われない。jarの追加やplugin.xmlの変更は比較的少ないのでまぁそれでも良いが、javaファイルの変更は頻繁に行われるはずで、それではまずい。before_prepareでjavaファイルのコピーをしているのはこのため。
カスタムプラグインのアンインストール
ここで一度「ionic plugin rm ex.customplugin」でアンインストールして次の項目を確認する。
- platforms/android/assets/www/plugins/ex.customplugin/customplugin.jsが削除されているか?
- platforms/android/libs/内のandroid-support-v4.jarとandroid-support-v7-appcompat.jarは削除されているか?
- platforms/android/res/xml/config.xml内の「ex.customplugin.CustomPlugin」は削除されているか?
カスタムプラグインの再インストールスクリプトを作成
plugin.xmlの編集やjava/jarファイルの追加などを行う場合にはプラグインのインストール・アンインストールを繰り返すことになるので、このようなスクリプトを用意しておく。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ionic plugin rm ex.customplugin | |
ionic plugin add plugins-custom/ex.customplugin |
「chmod 744 reinstall-custom-plugins.sh 」で実行権限を与えておくのを忘れずに。
カスタムプラグインをionicで動作確認
これでカスタムプラグインの導入は完了!最後にionicプロジェクトでの動作確認をする。
www/index.htmlをこのように編集する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> | |
<title></title> | |
<link href="lib/ionic/css/ionic.css" rel="stylesheet"> | |
<link href="css/style.css" rel="stylesheet"> | |
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above | |
<link href="css/ionic.app.css" rel="stylesheet"> | |
--> | |
<!-- ionic/angularjs js --> | |
<script src="lib/ionic/js/ionic.bundle.js"></script> | |
<!-- cordova script (this will be a 404 during development) --> | |
<script src="cordova.js"></script> | |
<!-- your app's js --> | |
<script src="js/app.js"></script> | |
</head> | |
<body ng-app="starter" ng-controller="AppCtrl"> | |
<ion-pane> | |
<ion-header-bar class="bar-stable"> | |
<h1 class="title">Ionic Blank Starter</h1> | |
</ion-header-bar> | |
<ion-content> | |
<!-- ここにボタンを追加 --> | |
<button class="button button-block button-positive" | |
ng-click="onClickBtnShowNotification();"> | |
ノーティフィケーション表示 | |
</button> | |
</ion-content> | |
</ion-pane> | |
</body> | |
</html> |
www/js/app.jsをこのように編集する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ionic Starter App | |
// angular.module is a global place for creating, registering and retrieving Angular modules | |
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) | |
// the 2nd parameter is an array of 'requires' | |
angular.module('starter', ['ionic']) | |
.run(function($ionicPlatform) { | |
$ionicPlatform.ready(function() { | |
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard | |
// for form inputs) | |
if(window.cordova && window.cordova.plugins.Keyboard) { | |
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); | |
} | |
if(window.StatusBar) { | |
StatusBar.styleDefault(); | |
} | |
}); | |
}) | |
.controller('AppCtrl', ['$scope', '$ionicPlatform', function($scope, $ionicPlatform) { | |
console.log('コントローラー初期化'); | |
//ここにボタンをクリックした時の動作を追加 | |
$scope.onClickBtnShowNotification = function() { | |
console.log('ボタンクリック'); | |
if (navigator.customplugin) { | |
navigator.customplugin.showNotification('ionicからノーティフィケーション', 'ionic内でテキスト設定'); | |
} | |
}; | |
}]); |
「ionic run android」でAndroidの実機で実行。するとこのように表示される。
「ノーティフィケーション表示」のボタンをクリックすると、このようにノーティフィケーションが表示される。
つまり、ネイティブアプリケーションと同様に、カスタムプラグインを使ってionicからノーティフィケーションを表示できるようになったわけだ。
ワークフローの再確認
ここで安心してはいけない。目的はあくまでワークフローの構築。カスタムプラグインを変更して素早くionicのプロジェクトに反映させられるかを確認しなくてはならない。
AndroidStudioに戻り、CustomPlugin.javaのshowNotification()メソッドの1行目に「Toast.makeText(context, "ノーティフィケーション表示", Toast.LENGTH_LONG).show();
」を追加してネイティブのトーストを表示してみよう。実行するとこのようになる。
さて、ionicでも同様に動作するだろうか?「ionic run android」で実行。するとこのようになる。
このように、カスタムプラグインのJavaソースを変更してネイティブで動作を確認しつつ、その後にコマンド一発でionicでも動作を確認できるようになったわけだ。
各プロジェクトのダウンロード
いや〜大変(^^);
customplugin(ionicプロジェクト)とcustomplugin-android(AndroidStudioプロジェクト)はgithubにアップしてある。
junkoro/customplugin
junkoro/customplugin-android
コメント
コメントを投稿