
こんにちは、コンサルティングサービス本部の朝日です。
今回はCordovaとBlocklyを組み合わせれば、スマホの機能を使えるScratchもどきが作れるんじゃないかと思ったので、Androidで試しに作ってみました。
BlocklyはiOSやAndroidのネイティブアプリ向けのものもありますが、今回はCordovaと組み合わせて使いたいのでfor Webを使います。
今回使ったもの
Node.js v8.11.3
Android Studio v3.1.3
Java v1.8.0 (Android Studio付属のものを使用)
Apache Cordova v8.0
Cordovaの準備
Apache Cordovaの公式ページに基づいて、インストールします。
GET STARTEDの内容に沿って、ブラウザでMyAppを表示できるところまで進めます。
実行できたら下記のような画面が表示されるはずです。
Androidで動かしてみる
次は、プロジェクトにandroidサポートを追加して、
cordova platform add android
実機をUSB接続して実行します。(Android側ではUSBデバッグをONにしておいてください)
cordova run android
もしも
You have not accepted the license agreements of the following SDK components:[Android SDK Platform 26].
というエラーが出た場合は、Android StudioのSDK ManagerでAPI Level 26をインストールしましょう。
ここまでできたら準備完了です。
Blocklyを導入する
まずBlocklyのサイトからzipをダウンロードして中身をMyAppのwwwフォルダに展開してください。
Blockly用のコードを追加する
今回は導入が簡単なFixed-sized Workspace方式にしてみます。
デフォルトで生成されている、index.html、js/index.jsを変更します。
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<title>Hello World</title>
</head>
<body>
<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
<xml id="toolbox" style="display: none">
<block type="controls_repeat_ext"></block>
<block type="math_number"></block>
<block type="text"></block>
<block type="text_print"></block>
</xml>
<script src="blockly_compressed.js"></script>
<script src="blocks_compressed.js"></script>
<script src="msg/js/ja.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
js/index.js
function bindEvents() {
console.log("bindEvents");
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady() {
console.log("onDeviceReady");
}
bindEvents();
// Blocklyの初期化
var workspacePlayground = Blockly.inject('blocklyDiv', {
toolbox: document.getElementById('toolbox'),
media: 'media/',
sounds: false,
});
ここまでで、cordova run browserで実行すると下記のような画面が表示されてブロックの組み立てまでできるはずです。(もちろんcordova run androidで実機で実行することもできます)
コード実行ボタンを作成する
このままだと作ったコードの実行ができないので、少し追加します。
index.html
・buttonタグとjavascript_compressed.jsの読み込みを追加
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<title>Hello World</title>
</head>
<body>
<button id="exec">実行</button>
<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
<xml id="toolbox" style="display: none">
<block type="controls_repeat_ext"></block>
<block type="math_number"></block>
<block type="text"></block>
<block type="text_print"></block>
</xml>
<script src="blockly_compressed.js"></script>
<script src="blocks_compressed.js"></script>
<script src="javascript_compressed.js"></script>
<script src="msg/js/ja.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
js/index.js
以下のロジックを追加。
・clickイベント時にBlockly.JavaScript.workspaceToCodeを使ってブロックからJavaScriptコードを取得
・evalで取得したコードを実行
function bindEvents() {
console.log("bindEvents");
document.addEventListener("deviceready", onDeviceReady, false);
document.getElementById("exec").addEventListener("click", onButtonClicked, false);
}
function onDeviceReady() {
console.log("onDeviceReady");
}
function onButtonClicked() {
console.log("onButtonClicked");
var code = Blockly.JavaScript.workspaceToCode(workspacePlayground)
alert(code);
eval(code);
}
bindEvents();
// Blocklyの初期化
var workspacePlayground = Blockly.inject('blocklyDiv', {
toolbox: document.getElementById('toolbox'),
media: 'media/',
sounds: false,
});
これで、実行ボタンを押すと組み立てたブロックのコードが実行できるはずです。
カスタムブロックを使ってCordova Pluginを呼び出す
ここまでだとBlocklyの標準的な部品しかないので、カスタムブロックとCordova Pluginを組み合わせてスマホ特有の機能を使ってみます。
Cordova Pluginの導入
今回は、Cordova Text-to-Speech Pluginを使ってみます。
cordova plugin add cordova-plugin-texttospeech
で追加です。
カスタムブロックの作成
次に、Text-to-Speech Pluginを呼び出すカスタムブロックを作成します。
カスタムブロックは、Blockly Developer Toolsを使用します。
上記のようにブロックを組み立てて、Block DefinitionとGenerator stubのJavascriptコードを、新規に作成したblocks/tts.jsにコピペします。
blocks/tts.js
Blockly.Blocks['tts'] = {
init: function () {
this.appendValueInput("str")
.setCheck("String");
this.appendDummyInput()
.appendField("を話す");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(160);
this.setTooltip("");
this.setHelpUrl("");
}
};
Blockly.JavaScript['tts'] = function (block) {
var value_str = Blockly.JavaScript.valueToCode(block, 'str', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var code = '...;\n';
return code;
};
コード部分の作成
生成されたコード部分を、Text-to-Speech Pluginを呼ぶように変更します。
blocks/tts.js
var code = 'TTS.speak({text:' + value_str + ', locale: "ja-JP"});\n';
index.htmlを変更して、カスタムブロックの表示を追加します。(blockタグおよびscriptタグ)
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<title>Hello World</title>
</head>
<body>
<button id="exec">実行</button>
<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
<xml id="toolbox" style="display: none">
<block type="tts"></block>
<block type="controls_repeat_ext"></block>
<block type="math_number"></block>
<block type="text"></block>
<block type="text_print"></block>
</xml>
<script src="blockly_compressed.js"></script>
<script src="blocks_compressed.js"></script>
<script src="javascript_compressed.js"></script>
<script src="msg/js/ja.js"></script>
<script type="text/javascript" src="blocks/tts.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
Text-to-Speech Pluginはブラウザでは動かないので、実機で実行してみてください。
デバッグ
ブラウザでの実行の場合、Chromeのデベロッパーツールでコンソールなどが確認できますが、実機の場合は、アプリが動いている状態で、ChromeのデベロッパーツールでMore tools→Remote devicesを実行すると、下記のような画面になるはずですので、Inspectボタンを押すと、Console出力が確認できます。
さいごに
とりあえずBlocklyでAndroidのTextToSpeech機能を使うところまではできました。
Cordova PluginのあるものならJavaScriptを使って簡単にアプリを組めるのは良いのですが、Pluginがない機能を使いたいときは大変そうですね。