JapanTaxi Advent Calendar 2018 16日目の記事です。
日本ではウェアラブルOSといえばAppleWatchに搭載されているWatchOSが知られていますが、GoogleでもWear OS By GoogleというウェアラブルOSが提供されています。 この記事ではWear OS by Google向けウェアラブルアプリ開発を始めるための準備やウェアラブルアプリ向けのUIを簡単に実装できるWear UI Libraryについて紹介します。
GoogleのウェアラブルOSは2014年6月にAndroid Wearという名称のAndroidベースの独立したウェアラブルOSとして提供されましたが、2018年3月にWear OS by Google 1.0 としてリニューアルされ、2018年12月現在ではWear OS by Google 2.1が最新バージョンとなっています。
Wear OS 向けの開発機能は以下のものが提供されています。
今回は ウェアラブルアプリの作成 について、スタンドアロンアプリの開発環境の準備からウェアラブル用レイアウトの簡単な利用法について紹介します。
Android Wear 1.xではウェアラブルアプリのAPKはスマートフォン側のAPKに内包する必要があり、あくまでスマートフォンと連動する機能として提供されていました。しかしAndroid Wear 2.0よりスタンドアロンアプリが導入されたことによりウェアラブル用APKをスマートフォンのAPKに内包する必要がなく、ウェアラブルデバイス上で単独動作し、GooglePlayからの直接インストールも可能となりました。国内ではAndroid Wear 1.xのデバイスはあまり流通していないので特別な理由がない限りはスタンドアロンアプリとして開発するのがよいでしょう。
スタンドアロンアプリの開発を行うためにはAndroid Wear 2.0のベースであるAndroid7.1.1(APILevel 25)以上の開発環境が必要となります。
android {
...
defaultConfig {
minSdkVersion 25
...
}
}
マニフェストに以下の定義をすることでWearOSアプリとして認識されます。
ウェアラブルアプリをインストールするにはウェアラブルデバイスの実機かエミュレーターを用意する必要があります。
実機にインストールするには通常のAndroid端末同様に開発者オプションを有効にしてデバッグを有効にする必要があります。
Settings→System→Aboutを開きBuild numberを7回タップして開発者オプションを有効にします。
Settings→Developer options→ADB debuggingをONにします。
これでUSB接続であればデバックが可能ですがWear OSを搭載しているデバイスの多くは無接点充電を採用しており、USB接続ができません。その場合は次のような無線接続でデバッグを行うことが可能です。
Settings→Developer options→Debug over Wi-FiをONにします。(表示されるウェアラブルデバイスのIPアドレスは後ほどで利用します)以下のコマンドを実行しADBをTCP/IP接続モードに変更します。
$ adb tcpip 5555
restarting in TCP mode port: 5555
Debug over Wi-FiをONにした際に表示されたIPアドレスに対してADB接続します。
$ adb connect xxx.xxx.xxx.xxx
結果が以下のようになる場合はウェアラブルデバイス側で接続を許可するか表示されるので許可を選択する必要があります。
failed to authenticate to xxx.xxx.xxx.xxx:5555\
正しくされると以下の表示になります。
connected to xxx.xxx.xxx.xxx:5555
接続の解除する際は以下のコマンドを実行します。
$ adb disconnect
disconnected everything
※Wi-Fi経由でデバッグするにはウェアラブルデバイスとAndroidStudioを実行しているデバイスが同一のLANに接続している必要があります。
Settings→Developer options→Debug over BluetoothをONにします。
ウェアラブルデバイスとペアリングしているスマートフォンをAndroidStudioを実行しているデバイスにADB接続し、スマートフォン内のWearOSアプリ内でBluetooth経由のデバッグをONにします。
以下のコマンドを実行して特定のポートへの接続をウェアラブルデバイスに転送します。(ポート番号は任意のもので大丈夫です)
$ adb forward tcp:4444 localabstract:/adb-hub
設定したポート番号で接続します。
$ adb connect localhost:4444
connected to localhost:4444
接続が成功するとWearOSアプリでは以下の表示になります。
接続を解除するにはスマートフォンのADB接続を解除するか以下のコマンドを実行します。
$ adb disconnect
disconnected everything
ここまで実機との接続について記載しましたが、ウェアラブルデバイスの仮想デバイスを作成して接続する方法もあります。仮想デバイスの作成については従来のAndroidデバイスと同じくAndroidStudioからTools→AVD Managerを起動し、Create Virtual Device→Wearで行います。
WearOSデバイスのディスプレイは以下の種類から作成することができます。
この内、RoundとRound ChinはWear OSの特徴の一つでもある特殊な形状のディスプレイです。従来のアナログな時計と同じ円形の形状を保ちつつ円形のディスプレイに最適化されたUXを実現するためのサポートライブラリが提供されています。
Wear OS 向けウェアラブルアプリでは画面が小さいことや前述した円形ディスプレイなど通常のスマートフォンとは異なる配慮が必要となります。ウェアラブルに特化したUIコンポーネントを利用できるWear UI Libraryというサポートライブラリが提供されているため、その一部を紹介します。
サポートライブラリとしての提供なので他のサポートライブラリとのバージョンを合わせてください
dependencies {
implementation "com.android.support:wear:$support_lib_version"
}
従来のAndroidアプリ同様にボタンを配置した場合、以下のよう表示になります。
Squareでは問題がありませんがRoundだとボタンの端が見切れてしまっています。円形ディスプレイでも見切れないように表示するにはBoxInsetLayoutを利用します。
重要なのはapp:boxedEdges="all"の箇所でこの指定をすると円形ディスプレイの時に上下左右方向が見切れないように調整してくれます。リストなどで上下は制限したくない場合などはapp:boxedEdges="left|right"とすることで左右のみの調整も可能です。
ウェアラブルデバイスは画面が小さいので操作した結果を大きなアニメーションで見せることで遠目でもわかりやすくなります。その機能を提供しているのがConfirmationActivityです。利用方法は簡単で呼び出す際に用意されているパラメータとメッセージを付与するだけです。
button1.setOnClickListener {
val intent = Intent(this, ConfirmationActivity::class.java).also {
it.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION)
it.putExtra(ConfirmationActivity.EXTRA_MESSAGE, "success")
}
startActivity(intent)
}
button2.setOnClickListener {
val intent = Intent(this, ConfirmationActivity::class.java).also {
it.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.OPEN_ON_PHONE_ANIMATION)
it.putExtra(ConfirmationActivity.EXTRA_MESSAGE, "open on phone")
}
startActivity(intent)
}
button3.setOnClickListener {
val intent = Intent(this, ConfirmationActivity::class.java).also {
it.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.FAILURE_ANIMATION)
it.putExtra(ConfirmationActivity.EXTRA_MESSAGE, "failure")
}
startActivity(intent)
}
ウェアラブルデバイスではタップ領域が小さいこともあり操作のたびにダイアログが表示されると億劫に感じてしまいがちです。その場合は都度ダイアログ出すより、一定時間キャンセルの時間を設けてキャンセルされなければ処理を進めるUIを採用すればタップ回数が減らせることができます。CircularProgressLayoutを利用すればそのようなUIが簡単に実装できます。
circularProgress.let{
it.setOnTimerFinishedListener {
val intent = Intent(this, ConfirmationActivity::class.java).also {
it.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION)
it.putExtra(ConfirmationActivity.EXTRA_MESSAGE, "success")
}
startActivity(intent)
finish()
}
it.setOnClickListener {
Toast.makeText(this, "canceled", Toast.LENGTH_SHORT).show()
circularProgress.stopTimer()
finish()
}
it.totalTime = 3000
it.startTimer()
}
円形ディスプレイでも無駄なくスクロールできるようにウェアラブルデバイス向けのRecyclerViewとしてWearableRecyclerViewが用意されています。
使い方は非常に簡単でlayoutManagerにWearableLinearLayoutManagerを設定するだけです。adapterは従来のRecyclerViewで利用しているRecyclerView.Adapterがそのまま利用可能です。
wearableRecyclerView.let {
it.isEdgeItemsCenteringEnabled = true
it.layoutManager = WearableLinearLayoutManager(this@WearableRecyclerViewActivity)
it.adapter = adapter
}
スワイプでViewGroupの削除を実装できるSwipeDismissFrameLayoutもあります。これはRecyclerViewにItemTouchHelperを追加してItemTouchHelper.ACTION_STATE_SWIPEを指定した場合と同様の動きが簡単に実現できるウェアラブル向けレイアウトです。WearableRecyclerViewとの相性も良く、簡単に実装することが可能です。
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder.itemView.swipeDismissLayout.addCallback(object : SwipeDismissFrameLayout.Callback() {
override fun onDismissed(layout: SwipeDismissFrameLayout) {
holder.itemView.visibility = View.INVISIBLE
listener?.onDismiss(holder.adapterPosition)
}
})
holder.itemView.visibility = View.VISIBLE
holder.itemView.rowText.text = list[holder.adapterPosition]
}
いつものAndroidとは違うウェアラブルに特化したUIはいかがでしたでしょうか?Wear UI Libraryで提供されているコンポーネントは他にも色々あるので興味があれば触ってみもらえればと思います。最後まで読んでいただきありがとうございました!
Mobility Technologies では共に日本のモビリティを進化させていくエンジニアを募集しています。話を聞いてみたいという方は、是非 募集ページ からご相談ください!