Androidで動くBASICでHTMLをUIやWEBAPIで利用する（ BASIC プログラミング ）

BASIC!は、Androidで動くBASIC インタープリタです。詳しくは以下をどうぞ。

* [AndroidでBASICを使う](http://qiita.com/basictomonokai/items/25bcb21ec69c00e9ad23)

BASIC!は昔ながらのBASICらしいUIであるコンソール／グラフィックの２つのモードとHTMLモードの３つのモードがあります。

##1.HTMLモード

HTMLモードは、AndroidのアプリらしいHTMLを利用したUIが作れるモードです。例えば以下の例1、例2ようなHTML画面をBASIC!のフロントエンドUIとして利用可能です。

私はHTMLやjavascriptは初心者なので説明不足な部分があると思いますがご容赦ください。

* 例1 品川区オープンデータプログラム

>以下の画像の通り、避難所情報のボタンを押すと地図画面に遷移してます。
>
>![1443450133z.jpg](https://qiita-image-store.s3.amazonaws.com/0/35574/9a1e610c-f724-5018-2905-0fea62d952c6.jpeg)
>
>* 品川区オープンデータプログラムのテスト動画(ＢＡＳＩＣ！友の会)
[![youtube動画表示エリア](http://img.youtube.com/vi/-IefB7O-Fo0/0.jpg)](http://www.youtube.com/watch?v=-IefB7O-Fo0) 

* 例2 画像の感情判定プログラム

>以下の画像の通り、画像のURLを入力する事によりマイクロソフトのエモーションＡＰＩで感情判定して結果を表示します。
>
>![1453034288.jpg](https://qiita-image-store.s3.amazonaws.com/0/35574/222ba85e-1228-4fdb-8bb1-759cceb1e0df.jpeg)
>
>* 画像感情判定プログラムのテスト動画(ＢＡＳＩＣ！友の会)
[![youtube動画表示エリア](http://img.youtube.com/vi/jSc-kgnB6OU/0.jpg)](http://www.youtube.com/watch?v=jSc-kgnB6OU) 

本稿では例2の画像の感情判定プログラムを題材にHTMLモードのプログラムの概要を説明します。

##2.HTMLモードの利点、欠点


まず、HTMLモードの利点、欠点について説明します。


###2-1.利点

HTMLモードの利点としてはHTML,CSS,javascriptが利用出来ることです。具体的には以下の点が挙げられます。

* スタイルシート等でわかりやすいUIが作成可。
* jqueryやCSSのCDNやライブラリも一部利用可。
* javascriptのWEBAPIも利用可。
* HTML⇒BASIC!のプログラムの間のインターフェイスも簡単に実装可能。

つまり、ウェブサイトの作成イメージで画面が作成でき、javascript APIで取得した結果をBASIC!のプログラムに受け渡してネイティブの処理が実行可能になります。JavascriptやCSSのサンプルやハウツーを公開しているサイトはとても多いので活用できると思います。

###2-2.欠点

ただし、BASIC!に搭載されたWebView機能の制約が原因と想定していますが、全てのjavascript、CSS機能が利用できるわけでは無いです。例えば、判っている限りでは以下の機能は使えませんでした。

* CSS3 アニメーションは動かないモノが多い
* canvasのtoDataURL() メソッドは動かない
* File APIでローカルファイルを扱えない
* three.js等の3Dライブラリは動かない

さらにAndroidのメモリ管理の影響を受けることにより、メモリ逼迫時にHTMLモードのプログラム実行時に他のアプリを実行し、マルチタスクボタンを押した場合の挙動に以下の問題があります。ちょっと不便だと思います。

>マルチタスクボタンを押してHTMLモードのプログラムを選択した場合に画面真っ白の無応答状態になる場合があり、この場合スワイプするなどタスクをキルするしか方法がない。
>プリインアプリが多く、メモリがとても逼迫しているASUS MeMo Pad7(me176c)などで良く発生する。

##3.HTMLモードの仕組み

基本的なHTMLモードの流れについては下図の通りです。この図に従い説明します。

>![Clipboard03.jpg](https://qiita-image-store.s3.amazonaws.com/0/35574/dc5bc719-ff59-88a6-ba7d-9f1b56d295db.jpeg)


* B-1.雛形HTMLファイルの読込


>BASIC!のファイル入力命令であるgrabfileで読込します。
>

```
grabfile outhtml$,"xxx.html",1
```

* B-2．HTMLデータの一部を置換

>BASIC!の文字列置換関数であるreplace$で置換します。
>

```
outhtml$=replace$(outhtml$,"@@@1@@@",clpx$)
```

* B-3．HTMLモードの開始

>BASIC!のHTMLモードを開始します。
>

```
html.open
```

* B-4．HTMLのロード

>BASIC!側でHTMLデータをロードします。
>

```
html.load.string outhtml$
```

* H-1．HTMLの表示

>HTMLモードの画面でHTMLデータを表示します。

* H-2．以下のいずれかによりデータをBASIC!に送信

>HTMLモードの画面でのアクションに伴いデータをBASIC!側に送信します。ここでは一番BASIC!独自の方法である「H-2-4． Javascript内でAndroid.datalink呼出」のHTMLを記載します。
>
>javascript側ではBASIC!にデータを送る為の専用命令であるAndroid.dataLinkを呼び出しています。Android.dataLinkでデータを送信する場合は、データはエンコードされないでそのまま送られます。
>※Formをsubmitした場合はAndroid.dataLinkを経由ぜずにBASIC!側へデータが送られます。その場合エンコードされますのでBASIC!側でデコードする必要があります。
>

javascript
```
<script type="text/javascript">
    function doDataLink(data) {
        Android.dataLink(data);
    }
</script>
```
>
>HTML側ではボタン等を作成してonclickでjavascriptを呼び出すだけです。
>

HTML
```
<a id="buttonx" onmouseover="this.style.background='#43cd80'" onmouseout="this.style.background='#337fcc'" onclick="this.style.background='#43cd80';doDataLink('//x//')">終了</a>
```

* B-5．HTML⇒BASIC!へのデータ受信待ち

>BASIC!側でHTMLからデータ送信を無限ループで待ちます。html.get.datalink命令でHTML側からデータが送信されたかチェックします。
>

```
do
  html.get.datalink data$
until data$ <> ""
```

* B-6．受信したデータにより処理

>BASIC!側で受信したデータにより処理を行います。HTML側から送られたデータの先頭４バイトはデータの種類なのでそれに従い処理を分けます。
>

```
type$ = LEFT$(data$, 4)

data$ = MID$(data$,5)

! Act on the data type
! Shown are all the current data types

SW.BEGIN type$

 ! Back Key hit.
 ! if we can go back then do it
 SW.CASE "BAK:"
  PRINT "BACK key: " + data$
  popup "強制終了します",0,0,0
  html.close
  pause 2000
  exit
  SW.BREAK

 ! A hyperlink was clicked on
 SW.CASE "LNK:"
  PRINT "Hyperlink selected: "+ data$
  popup "想定外のデータ受信 強制終了します",0,0,0
  pause 5000
  html.close
  exit
  SW.BREAK

 ! An error occured
 SW.CASE "ERR:"
  PRINT "Error: " + data$
  popup "エラーが発生しました 終了します",0,0,0
  pause 2000
  html.close
  exit
  SW.BREAK

 ! User data returned
 SW.CASE "DAT:"
  ! Check for Exit
  IF data$ = "Exit"
   PRINT "User ended demo."
   HTML.CLOSE
   popup "想定外のデータ受信 強制終了します",0,0,0
   pause 5000
   exit
  else
   msx$=data$+" が選択されました"
   popup msx$,0,0,0
   html.close
   pause 2000
  ENDIF
  SW.BREAK

 ! Form data returned.
 ! Note: Form data returning
 ! always exits the html.

 SW.CASE "FOR:"
  PRINT "Form data: "+data$
  popup "想定外のデータ受信 強制終了します",0,0,0
  pause 2000
  HTML.CLOSE
  exit
  SW.BREAK

 SW.DEFAULT
  PRINT "Unexpected data type:", type$ + data$
  popup "想定外のデータ受信 強制終了します",0,0,0
  pause 2000
  HTML.CLOSE
  exit

SW.END
```

* B-7．必要なら１や５に戻る
* B-8．HTMLモードの終了

>必要であればgoto文などで上の適切な場所にもどります。必要がなければBASIC!のHTMLモードを終了します。
>

```
html.close
```

##4.Webapiとの連携について

「例2 画像の感情判定プログラム」は動画を見ていただければわかるとおり上記の「3.HTMLモードの仕組み」で説明した内容を繰り返しているだけです。具体的には正常ケースの動作は以下のとおりです。

* 画像URL入力画面用雛形HTMLファイル読込。
* クリップボードから画像のURLを取得してHTMLデータの一部を置換して表示。
* 送信ボタンを押されたら画像URL欄のデータをgetElementById()で取得してAndroid.dataLinkでデータ送信。
* エモーションAPI呼出用雛形HTMLファイル読込。
* 画像URL欄のデータでHTMLデータの一部を置換して表示。
* エモーションAPIが自動実行され、感情判定の処理結果をAndroid.dataLinkでデータ送信。
* 感情判定の処理結果を編集。
* 感情判定結果画面表示用雛形HTMLファイル読込。
* 編集済の感情判定処理結果でHTMLデータの一部を置換して表示。
* 継続または終了のボタンを押されたらAndroid.dataLinkでデータ送信。
* データの内容によって継続/終了の処理を行う。

少しだけ補足すると実際にこのプログラムで用意しているリソースは７本になります。ちょっと長いですし、参考にする人がいるとは思えませんが一応ソースは別サイト( http://pastebin.com/ )に貼っておきます。

* [メインプログラム](http://pastebin.com/dq2dYfwQ)
* [画像URL入力画面用外部関数（子プログラム）](http://pastebin.com/VxX2uSdr)
* [エモーションAPI呼出用外部関数（子プログラム）](http://pastebin.com/YHHeM6T7)
* [感情判定結果画面表示用外部関数（子プログラム）](http://pastebin.com/EQ74qW4m)

* [画像URL入力画面用雛形（HTMLファイル）](http://pastebin.com/bjkQvv88)
* [エモーションAPI呼出用雛形（HTMLファイル）](http://pastebin.com/QETuKkdQ)
* [感情判定結果画面表示用雛形（HTMLファイル）](http://pastebin.com/5v9uN9JC)

本来はマイクロソフト社のエモーションAPIの説明が必要だと思いますが私自身に説明できるほどの知識はありません。ご参考までに提供元のリンクを貼っておきます。デモやコードサンプルもありますので興味のある方はご覧ください。

* [Microsoft Project Oxford Emotion APIs（英語）](https://www.projectoxford.ai/emotion)

##5.その他のWebapiとの連携方法

今回は、javascriptでのWebAPIとの連携について記載しましたがBASIC!では他にもWebAPIへの連携方法があります。本稿では概要のみ記載します。Javascriptを経由しないでもWebAPIとの連携ができます。

* graburl命令での連携（私自身の実績有り）

[kobo検索](https://webservice.rakuten.co.jp/api/koboebooksearch/) 、[OpenWeatherMap](http://openweathermap.org/forecast5) 、[じゃらん検索](http://www.jalan.net/jw/jwp0100/jww0105.do) 等、APIkeyをURLにセットするだけの簡単なAPIでつかえます。


```
graburl kekka$,"https://app.rakuten.co.jp/services/api/Kobo/EbookSearch/20140811?applicationId=[アプリID]&keyword=%97%BF%97%9D&sort=%2BitemPrice"
```

* http.post命令での連携（私自身の実績無し）

POST限定のWebAPIに使えるはずですが私自身は利用した事がありません。あくまでご参考です。

##6.まとめ

まとめると以下の通りとなります。BASIC!以外のAndroidで動くプログラム言語だと当たり前の事なのかもしれません。

* BASIC!にはBASICとしては珍しいHTMLモードというモードがある。
* HTMLモードは、HTML,CSS,javascrptの知識があれば画面UIを簡単に作れる。
* HTML⇒BASIC!プログラムへのデータ連携ができる。
> ※2016/10/21追記
> 　　BASIC!プログラム⇒HTMLへのデータ連携も可能な事が判りました。
> 　　詳しくは以下の記事をご覧ください。
> 　　[Androidで動くBASICでHTMLを動的に更新する](http://qiita.com/basictomonokai/items/e00b0324b71f71a0e556)


* 外部のCSS,javascrptのCDN、ライブラリーを利用できる。
* メモリーが逼迫している端末だとHTMLモードは課題がある。
* HTMLモードを使ってWebAPIとの連携ができる。
* HTMLモードを使わなくてもWebAPIとの連携ができる。

BASICを利用される方ならそこそこ便利ではないかと思っていますが自己満足かもしれません。