Android Weekly Topics

2021年12月第4週開発意欲をくすぐるスマートウォッチ「Bangle.js 2」(後編)

前回に続いてBangle.js 2です。今回は開発環境やアプリ開発をみていきます。

開発言語はJavaScript

アプリの開発言語はJavaScriptで、ES5の大部分とES6の一部機能が使えます。以下のサイトで使える機能が確認できます(ES5とES6のセクションです⁠⁠。筆者は実際に開発中、違いを意識したことはないので、言語仕様を意識する必要はなさそうです。

アプリ開発は、用意された専用ライブラリを使います。

メモリが少ないので人気のライブラリは使えないと考えたほうが良いのと、Unicodeもメモリが少ないことを理由にサポートしていないので日本語表示はできません。

ハードウェアリソースが限られた端末では、独自の開発環境や実装方法を学ぶ必要がありましたが、Web技術で開発ができるので導入と学習コストが低いのは、Bangle.js 2のメリットでもあり特徴です。

開発環境はクラウド

統合環境がクラウドで提供されているので、Webブラウザでアクセスして使います。

これには、Banglej.js 1とBangle.js 2のエミュレータが内蔵されています。アプリ開発には、実際の端末での動きや使用感を確認するために、実機があったほうが無難ですが、エミュレータを使えばある程度のところまでは開発が進められます。

端末との接続はWeb Bluetoothを使います。

対応ブラウザは、Google Chrome、Microsoft Edge、Operaに限られています。これらが動く環境であればPCを使う必要はないので、Androidタブレットでも開発ができます。

余談ですが、アプリのインストールもWeb Bluetoothに対応したWebブラウザを使います。Androidは、Google Chromeが使えるのでケータイでアプリをインストールできます。

統合環境は、いたせりつくせりの環境ではなく、エディタと実行環境を備えているだけです。たとえば、プロジェクトの概念もなく、アプリで使うアイコンなどのリソースを管理する機能やブレイクポイントをおいてデバッグする機能もありません。

とは言え、Bangle.js 2の場合、アプリで使えるメモリは200Kバイト程度が上限で、巨大なプログラムを開発できないので、いまくらいで十分かもしれません。

ウィジェットを自作してみました

Bangle.js 2で開発できるのは、アプリ、クロックフェイス、ウィジェットの3種類です。

ウィジェットは、常駐アプリと説明するのがわかりやすいです。これは、アプリやクロックフェイスの動作中でも動く小さなアプリで、Windowsのタスクトレイに表示されるアイコンのように、画面上下のどちらかに情報表示できます。このように、画面の一部を占有して情報が表示できる仕組みがあるスマートウォッチは稀有です。

たとえば、画面右上にあるバッテリ残量表示は、ウィジェットとして実装されています。システム関連の情報表示は変更できないのが常ですが、好みのウィジェットと置き換えることもできます。もちろん、自分でウィジェットが開発できるので、気に入った機能を持たせたものに置き換えることもできます。

このウィジェットがおもしろそうだったので自作してみました。開発したのは以下のようなものです。

  • 画面左上にカレンダーアイコンと共に今日の日付を表示する
  • 9時から20時までの間、0分にバイブレーションを動作
  • 同じ時間帯の9時、11時、13時、16時、18時の30分に、バイブレーションで手洗いを促す

このウィジェットで、ソースコードのボリュームはこのくらいです。

WIDGETS = {}; // <-- for development only

(() =< {
  let width = 24; // width of the widget
  let t_begin = 20;
  let t_end = 9;
  let t_hnd = { 9:1, 10:0, 11:1, 12:0, 13:1, 14:0, 15:0, 16:1, 17:0, 18:1, 19:0, 20:0 }; 
  
  const ICON_CALENDAR = 0;
  const ICON_CHIME = 1;
  const ICON_HAND = 2;
  
  let f_icon = ICON_CALENDAR;
  
  function draw( ) {
        
    g.reset(); // reset the graphics context to defaults (color/font/etc)
    
    // Draw icon
    if( f_icon == ICON_CHIME ) {
      g.drawImage(atob( 'GBgBAAAAAAAAABgAABgAADwAAP8AAf+AAf+AA//AA//AA//AA//AA//AA//AA//AA//AA//AB//gD//wAAAAADwAABgAAAAAAAAA' ), this.x, this.y) ;
    } else if( f_icon == ICON_HAND ) {
      g.drawImage(atob( 'GBgBAAAAAAwAAAwAAG2AAG2AAG2wAG2wAG2wAG2wAG2wAH/wAH/wAH/wGH/wHn/wH3/wD//wB//wA//wAf/wAP/wAH/gAD/AAAAA' ), this.x, this.y) ;
    } else {
      g.drawImage(atob( 'GBgBAAAAAwDAAwDAD//wH//4H//4H//4H//4GAAYGAAYGAAYGAAYGAAYGAAYGAAYGAAYGAAYGAAYGAAYH//4D//wAAAAAAAAAAAA' ), this.x, this.y) ;
	
      let date = new Date();
      
      g.setFontAlign(0,0);
      g.setFont('6x8');
      g.drawString( date.getDate(), (this.x+width/2)+1, this.y+13);    
    }
  }

  setInterval(function() {
  let today = new Date();
	
  f_icon = ICON_CALENDAR;
  if(( t_end <= today.getHours()) && ( t_begin < today.getHours())) {
      if( today.getMinutes() == 0 ) {
        f_icon = ICON_CHIME;
        Bangle.buzz(400,1);
        Bangle.buzz(800,0.1);
      } else if(( t_hnd[today.getHours()] == 1 ) && ( today.getMinutes() == 30 )) {
        f_icon = ICON_HAND;
        Bangle.buzz(400,1);
        Bangle.buzz(800,0.1);
        Bangle.buzz(400,1);
      }
    }
	
    WIDGETS['widdate'].draw(WIDGETS['widdate']);

  }, 1*60000 ); 
	  
  WIDGETS['widdate']={
    area : 'tl',
    width : width,
    draw : draw
  };
})()

Bangle.drawWidgets(); // <-- for development only

これはサンプルから派生したものですが、追加した部分は難しいことをしていません。ざっくり説明すると、setIntervalで内でいまの時間を確認して、Bandle.buzzでバイブレーションを動かす、draw関数で時間に応じてアイコンをウィジェットのクライアントエリアに描画しています。

アイコンの描画とバイブレーションの動作

アイコンは、通常は日付の入ったカレンダーアイコンを表示していますが、0分のときはベルアイコン、30分は手アイコンの表示に変更して、それぞれでバイブレーションの動きを変えています。

アイコンの変更は、ウィジェットのインスタンスに画像リソースを指定する使い方ではなく、以下のコードのように、自身のクライアントエリアに対して画像を描画します。

g.drawImage(atob( 'GBgBAAAAAAwAAAwAAG2AAG2AAG2wAG2wAG2wAG2wAG2wAH/wAH/wAH/wGH/wHn/wH3/wD//wB//wA//wAf/wAP/wAH/gAD/AAAAA' ), this.x, this.y) ;

描画は、用意されている独自のライブラリを使います。

画像ファイルはbase64に変換してコードに埋め込み、バイナリに変換してから描画します。この方法は一般的ではなくなりましたが昔に使われたテクニックです。この例は古いものですが、Web技術を応用してアプリが開発できるところは、Firefox OSやwebOSのようです。

バイブレーションは継続時間と強さが指定できます。

以下のコードでは、バイブレーションを最大の強さで400msec動かして、最小の強さで800msec動かしています。

Bangle.buzz(400,1);
Bangle.buzz(800,0.1);

音が鳴らせるとよかったのですが、Bangle.js 2にはスピーカがなく、しっかりと音が鳴らないので使いませんでした。

年末・年始のお休みにいかがでしょうか

駆け足ですが、このようにウィジェットであればカジュアルに開発ができます。

年末・年始のお休みを使ってエミュレータを使って遊んでみるのも良いかもしれません。年末までに端末を入手するのは時間的に厳しいですが、開発したプログラムが腕時計で動く様子を見るのは楽しいものです。

それでは皆さん、良いお年をお迎えください。今週は、このあたりで、また来年。

おすすめ記事

記事・ニュース一覧