FireタブレットでShowモードが使えなくなったので置き時計アプリを作ってみた
はじめに
先日、Room Screenというアプリをリリースしました。
スマートディスプレイ風のシンプルな置き時計アプリです。
天気予報やカレンダーの表示にも対応しています。
この記事では、このアプリを開発するに至った経緯や開発過程、今後の機能追加予定などまとめたいと思います。
実使用感の話と技術的な話とが混ざっているので、適宜読み飛ばしてください。
Showモードが使えなくなるまでの経緯
Echo ShowからFireタブレットへ
もともと私は、Ring(ネットワークカメラ)の監視用モニター代わりとして、Echo Show 5を使っていました。
モニター代わりとして買ったものの、時計や天気予報が表示されるのが、リビングでちょっと確認したいときに意外と便利でした。
また、Ringとの連携についても、動作検知をするとその通知が表示されるのはもちろん、定型アクションで、モーションを検知したときにアレクサにカメラを見せるよう呼びかけるアクションを追加しておくと、動作検知時にカメラの映像が自動で表示されるようになり、便利に使っていました。
しかし、最近になって動作が不安定になり、画面の切り替えが遅かったりカメラの映像が表示されなかったりすることが増えたので、買い替えることに。
画面が大きいほうがいいなということで、当初はEcho Showの大きい画面のものを買おうと思っていました。
しかし、調べてみると、FireタブレットにShowモードというものがあり、ShowモードでEcho Showのような画面表示ができると知りました。
FireタブレットならRingアプリで詳しくカメラの履歴を確認できるし便利じゃん!ということで、Fireタブレットを買うことに。
ちょうどプライムセールというのもあり、せっかくならということで、画面が大きくてスペックが高くWifi 6にも対応しているFire Max 11を買いました。
FireタブレットでのShowモードの使い心地
実際にFireタブレットでShowモードを使ってみて、予想以上に快適でした。
まず、そもそも動作が軽く、操作の反応が良いというのがありました。
Showモードについては、時計が隅に表示されるというのはEcho Show 5とは違いましたが(これはShowモードというより画面サイズによるレイアウトの違い)、良い意味でEcho Showと操作感が変わらず違和感なく使えました。
もとがタブレットというのもあって、Echo Showと比べるとマイク感度やスピーカーの品質は落ちるものの、個人的には許容範囲かなという感じでした。
また、Fireタブレットになったことで、アプリの通知が表示されるようになりました(Showモードでは上部に帯のように大きめの通知が表示される)。
そのため、Ringアプリでの画像付きの通知を確認できるようになり、これが結構便利に感じました。
(もちろん、スマホやPCでもRingの通知を確認できるのですが、リビングでちょっと確認できるというのは個人的に便利に感じるポイントです)。
この通知をタップすると、Ringアプリを開いてカメラ映像を詳細に確認できる代わりに、Showモードが解除されるため、再びShowモードを有効にする必要がありました。
しかし、Showモードは、ステータスバーをスワイプして表示される通知バーの一番上にあるスイッチボタンを押すことで有効にできるので、このShowモードを再び有効にするという手間はこれもまた許容範囲かなと感じました。
そんな感じで便利に使っていたのですが…
Showモードが使えなくなった
ある日、朝起きてFireタブレットを見てみると、OSアップデートされたとの表示が。
アップデートされたためShowモードが解除されたんだなぁと思い、ステータスバーをスワイプして表示される通知バーの一番上にあるShowモードのスイッチボタンを押そうとしたところ、なんとそのスイッチボタンがなくなっていました。
アップデート後でなんかバグったんだろうと再起動したものの特に変化はなく。
調べてみると、Amazonフォーラムでこの数日前からShowモードが使えなくなったとの報告が。
その報告の回答として、工場出荷状態にリセットしてみるように書いてあるものがあったので、試してみるも変化なし。
Amazonカスタマーサービスにチャットで問い合わせてみたところ、以下のような回答がありました。
私の問い合わせでははっきりとはしなかったものの、以下の記事によるとShowモードは廃止されたということのようです。
たしかに、ShowモードがAlexaアプリに移行するみたいな表示をみた記憶はありますが、それがShowモードの廃止を意味するとは思っていませんでした…
一旦Echo Show 5に戻した
Showモードが使えないならということで、一旦取っておいたEcho Show 5に戻してみることに。
しかし、動作のもっさり感が気になり、また、Fireタブレットの大きな画面に慣れたこともありかなり画面が小さく感じました。
せっかく買ったのもあり、どうにかFireタブレットを再びShowモードみたいに使いたい。
そこで、アプリを作ってみることにしました。
アプリを作ってみた
基本方針
とりあえず、さっと作ってしまおうということで、いつも通りFlutterでシンプルにアプリを作ることに。
また、自分に必要な機能を優先して作ることにしました。
必須な機能は以下の通り
- 時刻・日付表示
- 天気予報の表示
- フルスクリーン表示
- スリープしないようにする
- 画面の切り替え(自動・スワイプ)
一応、Alexaハンズフリー機能は使えるので、Alexaに呼びかけることはできるし(タイマー設定など)、Ringのカメラについてはアプリの通知バーが表示さえしてくれれば十分なので、アプリに必須な機能はこれでOK。
あと、Showモードにはなかったのですが、カレンダーも表示されると便利だなと思い(予定の確認ではなく今日がその月のどの位置にあるか視覚的に認識するため)、そのことも頭に入れておくことにしました。
天気予報API
天気予報を取得するには天気予報APIを使用する必要があるので、そのAPIの選定をすることに。
条件としては、無料で使用できることと海外の天気予報も取得できること(アプリストアで日本だけに公開するのはもったいない気がするので)。
有名なのは、OpenWeatherだと思うのですが、自宅の天気を見てみると特に最低気温がかなり異なる印象でした。
そこで、最低気温の精度がよりよい印象だったOpen-Meteoを使うことにしました。(あとサイトがスッキリしていてこっちを使いたくなったという個人的な気持ちも…)。
※なお、詳しくデータを比較検討し精度の正確性を検証したたわけではない点ご留意ください。
ありがたいことに、Flutterのパッケージでopen_meteoというOpen-Meteo APIを簡単に使えるものがあったので、これを使用しました。
※なお、OpenWeatherもOpen-Meteoも無料での使用には制限があるのでご注意ください。
時刻・日付表示
時刻表示については、Timer
を使うやり方とTicker
を使うやり方とがあるようですが、Ticker
の方が、Flutterの画面更新タイミングに合わせて実行される分、効率的かつ精度良く時刻が表示されそうだったので、Ticker
を使うことにしました。
参考記事↓
ただし、Ticker
で毎回setState
をしてウィジェットを再構築すると負荷が高そうなので、日時表示部分はValueNotifier
を使って更新して、setState
は1時間ごとに使って天気表示などを更新するようにしています。
参考記事↓
また、日時表示には、Intl
パッケージのDateFormat.Hm().format(time)
やDateFormat.MMMEd().format(time)
を使っています。
これにより、日時表示が端末の言語に対応した表示になります。
※ただし、私はVS Code拡張Flutter Intlを使って多言語対応をしているところ、今回のアプリは英語と日本語のみの対応にしたので、この日時表示も英語と日本語のみ対応となっています。
フルスクリーン・スリープ防止
フルスクリーン表示にするため、以下のコードを使いました。
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.immersiveSticky,
);
SystemUiMode
にいくつか種類があるようですが、SystemUiMode.immersiveSticky
は上下でのスワイプで一時的にステータスバーが表示されるので、これにしています。
参考記事↓
ただし、たまに他のアプリを開いた後フルスクリーンにならなくなる場合があるので、その場合はアプリを再起動してください。
今後改善できるか試してみたいと思います。
スリープ防止については、wakelock_plusパッケージを使いました。
カレンダー表示
カレンダー表示には、table_calendarパッケージを使いました。 今回は、予定の確認ではなく今日がその月のどの位置にあるか視覚的に認識するためにこのカレンダーを導入したため、あまりカスタマイズしませんでした(文字サイズ調整と今月にジャンプするボタンの追加のみ)。
余談ですが、カレンダーの綴りをいままでcalenderと勘違いしており、開発の途中でcalendarであることに気づいて変数を書き換えました…今回のアプリ開発で一番の学びだったかも(;o;)
画面の切り替え(自動・スワイプ)
- 時計
- カレンダー
- 1時間毎の天気(〜5時間後)
- 1時間毎の天気(6〜11時間後)
- 週間天気
という画面ができたのですが、この画面が自動で切り替わっていき、スワイプでも画面を切り替えられるようにするため、carousel_sliderパッケージを使いました。
30秒ごとに画面が自動で切り替わるよう設定しました。
設定画面
設定画面では、画面の表示内容の変更や天気予報関連(表示の有無、更新間隔、予報地点、温度の単位)を設定できるようにしました。
日時のみの表示にすることもできます。
また、私の開発するアプリではいつもadaptive_themeパッケージを使ってダークモードやテーマの色(colorSchemeSeed
)を変更できるようにしているので、今回のアプリでもこれを導入しました。
予報地点について
天気予報地点について、geolocatorパッケージを使って位置情報を取得しようとしたのですが、Fireタブレットで試したところ位置情報を取得できませんでした。
Fire Max 11を含むほとんどのFireタブレットにはGPSがついていないため正確な位置情報を取得できないのはわかっていたのですが、おおまかな位置情報(GPSを使わずWiFiなどを使う方法)を取得することもできませんでした(位置情報の権限の許可自体はできる)。
デバッグコンソールでは、com.enoiu.roomscreen requires the Google Play Store, but it is missing.
と表示されたので、Google Playサービスがないとそもそも位置情報の取得ができないようです?
以下のドキュメントを参考に、forceLocationManager
をtrue
にしてcom.google.android.gms
を除外してみると、上記のエラーは表示されなくなったものの、位置情報の取得はできませんでした。
仕方ないので、緯度と経度を手動で入力する機能を追加しました。
(geocodingパッケージを使って、地域名から緯度経度を取得する方法も検討したのですが、これにもGoogle Playサービスが必要なのかFireタブレットでデータを取得できませんでした)。
なお、Fireタブレットで位置情報を取得しようとするとエラーが発生するのですが、そのエラーを回避するようにできなかったので、グローバルな定数としてconst useAmazon = bool.fromEnvironment("AMAZON");
を定義し、Amazonアプリストアからダウンロードしたアプリでは位置情報を取得できないようにしています。
(Amazonアプリストアに提出するapkファイルをflutter build apk --dart-define=AMAZON=true
とビルドすることで、このuseAmazon
がtrue
になるようにしています)。
また、AndroidManifest.xml
で正確な位置情報を取得する権限である<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
を入れていると、多くのFireタブレットが対象デバイスとならないため(GPS機能がない端末)、おおまかな位置情報を取得する権限である<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
の方にしています。
そのため、Android端末での位置情報が実際の位置と少しずれることになるのですが、天気予報は数km単位の解像度で提供されるので、今回は特に問題にならないと認識しています。
予報地点の設定方法についてはこちらで詳しく説明しています。
実使用感について
Google PlayストアとAmazonアプリストアではすでに公開されており、App Storeについては現在審査中です。
10日くらいでつくったアプリですが、自分用に作ったというのもあってそこそこ快適に使えています。
シンプルな表示ですが、個人的にはこのシンプルさが好きなのでいい感じです。
また、実はShowモードでは通知バーは大きめに表示されるものの、他のアプリの通知音が鳴らなかったのですが、今回は普通のアプリなのでもちろん通知音が鳴ります。
そのため、Ringのカメラが動作を検知した際、Ringアプリから「しゃららーん」という通知音が鳴ってくれるのでこれはShowモードより良い点だなと思いました。
(もちろんAlexaの設定で動作検知があったことをShowモードでお知らせする機能もあったのですが、この機能は画面が一定時間そのお知らせ表示のままになってしまうため、この機能はほとんどオフにしていました。)
通知をタップしてRingのアプリでカメラを確認した後についても、このアプリに戻るだけなので、Showモードを再びオンにするよりもスムーズになりました(Showモードにする際は少々読み込みの時間があった)。
ただし、Showモードで使っていた「〜のカメラを見せて」と呼びかけてカメラの映像を見れる機能はAlexaハンズフリーでは利用できないようです(呼びかけると「わかりました」と反応はしてくれるもののその後何も起こらない)。
これに伴い、定型アクションでの設定(モーションを検知したときにアレクサにカメラを見せるよう呼びかけるアクションを追加しておくと動作検知時にカメラの映像が自動で表示される)も機能しませんでした。
この点はかなり残念ですが、通知をタップすればカメラの映像をすぐに開くことができるので、ここはぎり妥協できるラインかなと思っています。
今後の機能追加について
リリースまでこぎつけたので、一旦他のアプリの修正に戻る予定ですが、一応今後の機能追加についても考えています。
追加予定の機能は以下の通りです。
- 画像を背景に指定
- ホワイトボード
- おやすみモード
- 端末のカレンダー読み込み予定を表示
- 文字サイズの変更機能
まずは、画像を背景に指定できる機能です。Showモードではフォトフレームのように利用していた方も多いと思うので、画像を背景にしたり、時計を隅に表示し画像を表示する機能は今後つけたいと思います。
また、ホワイトボードについては、ちょっとメモを書いておくときに便利かなと思います。
楽譜閲覧アプリで書き込み機能を実装したことがあるので、この機能の実装は比較的簡単にできるかなというのもあります。
おやすみモードについては、夜寝てる間は自動的にダークモードにして時計のみの表示にするモードをオプションとして設定したいです。
カレンダーについては、device_calendarパッケージで端末のカレンダーに登録された予定を取得できるようなので、できればこの機能を実装したいと思います。
文字サイズについては、現在は端末の横幅に応じて自動で調整されるようになっているのですが、特にiPadなどの縦横比が4:3に近いような端末では少し小さめに表示されてしまうので、これも含め自動で調整されるようにするか、そもそもユーザーが文字サイズを変更できるようにするか検討したいです。
他のアプリの修正が一段落したら、このRoom Screenアプリの開発を再開したいと思います。
最後に
Showモードが復活するかどうかは不明なので、とりあえずアプリを作ってみましたが、個人的に必要なものはできたのでよかったです。
Amazonアプリストアだけでなく、PlayストアやApp Storeにもリリースしたので(App Storeについては現時点で審査中)、GoogleアシスタントやSiriをハンズフリーで利用できるようにして、AndroidやiOS端末で使ってみるのもいいかもしれません。
もちろん、日時のみの表示にしてシンプルな置き時計として使ってもいいと思います。
拙い文章でしたが、お読みいただきありがとうございました。
もし機能の要望や不具合などありましたら、お問い合わせからご連絡ください。
Discussion