雑文発散

«前の日記(2015-06-09) 最新 次の日記(2015-06-11)» 編集
過去の日記

2015-06-10 [長年日記]

[Pebble] そろそろ Pebble の開発についても体験しておこうと思ってチュートリアルを学んでみる #2

昨日の日記に書いた Pebble SDK のインストールを終えたところからの再開である。

Watchface(ウォッチフェイス)を作る

SDK のインストールが終わると、次にこれをやれと示されるのが、Build Your Own Watchface というチュートリアル。「Watchface」というのは、Pebble の時計画面のこと。これを自由に切り替えることができるのが Pebble の特徴でもある。

プロジェクトの作成

pebble-sdk をインストールすると、pebble というコマンドが追加される。こいつで、新しいプロジェクトを作ったり、アプリをビルドしたり、そのアプリを実機へインストールしたりする。イマドキよくある「メインコマンド名 + サブコマンド名」で実行するタイプだ。

この pebble コマンドのドキュメントは、Command Line Tool にまとまっている。

さっそくチュートリアルに従い、pebble new-project Tutorial1 というコマンドで Tutorial1 という新規プロジェクトを作ってみる。

% pebble new-project Tutorial1
Creating new project Tutorial1
/usr/local/Cellar/pebble-sdk/3.0/libexec/lib/python2.7/site-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning

なんか SSL 接続に関する Warning が出たけど、カレントディレクトリを見てみると、 Tutorial1 のプロジェクトはできていたので、いったんこのまま進める。

Pebble アプリのメタ情報は appinfo.json というファイルに記載するようだ。このファイルもプロジェクト作成時に自動生成されるみたい。今回は Watchface アプリなので、以下のところを変更しろとチュートリアルには書いてある。

"watchapp": {
  "watchface": true
}

あとは companyName も変えろとのこと。チュートリアルだし、そのまま Pebble AppStore へ公開するつもりもないので、今回は適当にいじった。

コードの作成

pebble new-project Tutorial1 を実行すると src/Tutorial1.c が自動生成されるが、ここではイチから作ることで、Pebble 用アプリの「カタ」を教えようとしているようだ。

超基本系は次のようになる。app_event_loop() の部分が Pebble SDK であれこれしてくれるルーチンみたいだ。

#include <pebble.h>

static void init() {

}

static void deinit() {

}

int main(void) {
  init();
  app_event_loop();
  deinit();
}

このカタから、まずは Window を表示してみようという話になっている。Window というのは、Pebble における表示領域みたいなものらしい。

チュートリアルのとおりに init() で Window を作って、deinit() で廃棄してやるようなコードを書く。

コンパイルとインストール

次のステップではコンパイルの方法が紹介されている。まずは、Window だけ作って表示する Watchface (つまり何も表示されない)を作って、その次に実際に文字を表示するというチュートリアルになっているようだ。

コンパイル

まずは言われるままにコンパイルしよう。コンパイルにも pebble コマンドを使う。pebble build でコンパイルが実行される。

% pebble build

実際にコンソールへ出力されたのはこんな感じだった。

% pebble build
Setting top to                           : /Users/norisuzu/work/pebble/Tutorial1
Setting out to                           : /Users/norisuzu/work/pebble/Tutorial1/build
Found Pebble SDK for basalt in:          : /usr/local/Cellar/pebble-sdk/3.0/Pebble/basalt
Checking for program gcc,cc              : arm-none-eabi-gcc
Checking for program ar                  : arm-none-eabi-ar
Found Pebble SDK for aplite in:          : /usr/local/Cellar/pebble-sdk/3.0/Pebble/aplite
Checking for program gcc,cc              : arm-none-eabi-gcc
Checking for program ar                  : arm-none-eabi-ar
'configure' finished successfully (0.070s)
Waf: Entering directory `/Users/norisuzu/work/pebble/Tutorial1/build'
[ 1/30] Start build for basalt:
[snip]
[27/30] report-memory-usage: build/aplite/pebble-app.elf build/aplite/app_resources.pbpack.data
-------------------------------------------------------
BASALT APP MEMORY USAGE
Total size of resources:        0 bytes / 256KB
Total footprint in RAM:         360 bytes / 64KB
Free RAM available (heap):      65176 bytes
-------------------------------------------------------
-------------------------------------------------------
APLITE APP MEMORY USAGE
Total size of resources:        0 bytes / 96KB
Total footprint in RAM:         360 bytes / 24KB
Free RAM available (heap):      24216 bytes
-------------------------------------------------------
[28/30] inject-metadata: build/basalt/pebble-app.raw.bin build/basalt/pebble-app.elf build/basalt/app_resources.pbpack.data -> build/basalt/pebble-app.bin
[29/30] inject-metadata: build/aplite/pebble-app.raw.bin build/aplite/pebble-app.elf build/aplite/app_resources.pbpack.data -> build/aplite/pebble-app.bin
[30/30] Tutorial1.pbw: build/basalt/pebble-app.bin build/basalt/app_resources.pbpack build/aplite/pebble-app.bin build/aplite/app_resources.pbpack -> build/Tutorial1.pbw
Waf: Leaving directory `/Users/norisuzu/work/pebble/Tutorial1/build'
'build' finished successfully (0.599s)

「BASALT APP」とか「APLITE APP」とか出てくる。これは appinfo.json の中にある targetPlatforms に関係ありそうだ。

"targetPlatforms": ["aplite", "basalt"],

「プラットフォーム」とあるので、おそらく Pebble のモデルを表しているんだろう。たぶんどこかに説明があるだろうし、この後で出てくるかなとも思うので、ここではそういうものとして置いておく。

さて、コンパイルが成功すると、build ディレクトリ内に .pbw という拡張子のファイルができる。これが Pebble へのインストール形式なんだそうだ。

インストール

実機へのインストール前に、iOS / Android の Pebble.app(「Pebble 上で動くアプリ」と「iOS / Android 用の Pebble アプリ」が紛らわしいので、「iOS / Android 用の Pebble アプリを「Pebble.app」と表記する)で「Developer Connection」の設定が必要とのこと。その方法は「Pebble Developer Connection」のページに説明がある。

簡単に言うと、設定メニュー(Settings)で「Developer Mode」を ON にすると、「Developer」メニューが現れるので、そこで接続設定を ON / OFF するという話だ。ON にしたままだと、同じネットワーク内の知らないヤツから勝手にインストールされる危険性もありそうだし、必要なときだけ ON にした方が良さそうな雰囲気を感じる。あと、電池の持ちとかにも影響があるかもしれない(本当のことは知らないけれど)

さて、Pebble アプリをインストールするには、この Developer メニュー内に表示される IP アドレスに対してインストールコマンドを叩けば良いようだ。チュートリアルの例だとこうなっている。

% pebble install --phone 192.168.1.78

また、IPアドレスについては環境変数でも指定できるようだ。この場合は --phone オプションが不要になる。

% export PEBBLE_PHONE=192.168.1.78
% pebble install

まぁ、どのみちシェルの履歴を使ってコマンドを叩くだろうから、実際にはどっちでもいいかなって気はする。

じゃあ実際にインストールしてみよう。

% pebble install --phone 192.168.1.78
[WARNING ] You are not logged in with your Pebble Account and will not be able to receive remote pins in the emulator. Please run 'pebble login' to connect your Pebble account.
[ERROR   ] Failed to install 'build/Tutorial1.pbw'

あれ、怒られた。WARNING は Cloud Pebble 関連のものかな。リモートのエミュレータの話みたいだから、ここでは今すぐ必要な話じゃない。問題は ERROR だ。

よく見たら、Pebble.app にもエラーが出ていた。

Pebble error

コマンドラインでのエラー表示も Pebble.app のエラー表示も原因を言ってくれないので、分かりにくいのだけど、ひとつ心あたりがある。SLOT の限界だ。

Pebble はインストールできるアプリの上限があり、それを「SLOT」と読んでいる。これがオレの Pebble 上でいま限界(ALL 8 SLOTS USED)の状態だった。Pebble.app の機能で、Pebble 本体からひとつアプリを削除して SLOT を開け、もう一度 install コマンドを実行したらインストールが成功した。

% pebble install --phone 192.168.1.78
[WARNING ] You are not logged in with your Pebble Account and will not be able to receive remote pins in the emulator. Please run 'pebble login' to connect your Pebble account.
[INFO    ] Installation successful
[INFO    ] JS: stopping app: 0000-0000-0000-0000-0000000000000 Futura Weather

最後の行の「Futura Weather」は、インストール前に動かしていた Watchface の名前だ。これを停止して、いまインストールしたアプリに切り替えたという意味だろう。

インストール後の Pebble の様子はこんな感じ。何も表示されていない。

Pebble App

Pebble.app から見ると、こんなふうに表示された。

Pebble App

Tutorial1 とも表示されているし、ここまでは成功ということだ。

テキストを表示する

ここからもう少しアプリっぽくなる。時計っぽい文字列を表示する話になる。Watchapp や Watchface でテキスト表示をするには TextLayer を使うのが良いそうだ。

Tutorial1.c を編集していく。

TextLayer は、Window を作った後で作成していく。この例で行くと main_window_load() の中で作っていく。TextLayer のサイズ、背景色、テキストの色と表示するテキストを定義し、更にフォントや表示位置も定義する。そして Window の子要素に TextLayer を追加するという流れのようだ。

それから、Window の利用が終了した時に TextLayer も消さないといけないようだ。この辺は勝手に改修してくれないみたいだ。さすが C 言語。

TextLayer は deinit() ではなく main_window_unload() の方で回収する。

この修正を行った後で、build & install をすると、Pebble 上に「00:00」が表示されるようになる。時計っぽい表示だけど、まだ固定のテキストなので何も動かない。ただ「00:00」が常に表示されているだけだ。

Pebble app

時刻表示

このチュートリアルでは、TickTimerService というイベントサービスを使って、時刻表示を実現するようだ。このサービスは、通常は分単位だけど、時間単位や秒単位でも指定したハンドラを実行してくれるそうだ。ただ、短い間隔で発火させると、それだけバッテリの減りが速いのでよく考えて使えって。

それから実際に時刻表示をする部分を update_time() として定義していく。24時間表示と12時間表示とかも切り替えできるようだ。この設定は今回のアプリの範囲ではなく、Pebble 本体の設定で 24/12 の切替ができるので、そこの値を持ってきて比較しているようだ。

タイマーへ登録する tick_handler() の中で、この update_time() を呼び出すことにより「1分ごとに現在時刻を表示する」という処理が動くわけだ。

また、アプリの起動時に(タイマー処理が走る前に)「いま」の時刻を表示するために update_time() を最初に一度だけ実行しておく。

これらの追加が終わったら、pebble buildpebble install を実行し、Pebble へアプリをインストールすると、時計表示が、、、出なかった。

Pebble app

どうも「最初の一回の update_time()」を init() の中に書いてしまっていたのが間違いで、本当は main_window_load() の最後に書くのが正解だったようだ。

そこを直して、また build & install を実行したら、今度こそ時刻表示ができた。

Pebble app

ここでこのチュートリアルは終了。次はカスタムフォントとビットマップイメージを扱うチュートリアル・パート2へ行けとあるので、進んでみよう。


もしかして気が付いたかも知れないけど、写真に写っている時計の時刻が飛んでいるのは(例えば8時から23時とかに)、そういうものなので特に間違いではない。この日記は一気に書き上げた訳ではなく、「英語のチュートリアルをセクションごとに読んで、実装して、写真を撮って、文章に残して」みたいなことを何度か繰り返して作ったメモがベースなのでこうなっている。


#3 へ続く