Google Maps API on Android Wear を試してみる


5月にリリースされていた*Google Maps API on Android Wear* ですが、遅ればせながら気になって使ってみました。使い方、所感などまとめておきます。

実際に使ってみて既に *Google Maps API for Android* を使用しているので、ほぼ同じ感じで使えそうだという印象です。
※ ただしUI面を除く

参考情報

* [公式ドキュメント](https://developers.google.com/maps/documentation/android-api/wear)
* [Google Geo Developers Blog](http://googlegeodevelopers.blogspot.jp/2015/05/the-world-on-your-wrist-google-maps-api.html)
* [ブログの日本語訳](http://googleforwork-japan.blogspot.jp/2015/06/android-wear-google-maps-api.html)

理解のために作成したサンプルアプリはGitHubにあります。
(ご利用される際はAPIキーを設定してください）

* [GitHub](https://github.com/droibit/mapsonwear)

## Google Maps API on Android Wear できることできないこと

*Google Maps API for Android* で動作する機能はほぼ使用できますが、幾つかデフォルトの動作が異なっていたり、無効になっています。

* マップツールバーが無効
* インドアマップがデフォルトでは無効に
* インドアマップはデフォルトの階を表示する（ピッカーが無効）
* タイルオーバーレイが無効


* アンビエントモード対応

ピンチズームなどのジェスチャ機能や、マーカーなどのシンボルの追加などなどの機能は変わらず使えますが、Wearの性能や画面の制約があるため、一部使えないようです。
（ドキュメントでは二本指の回転ができるとあったのですが、LG G Watchでは動作しなかった…。）

また、Android Wear側で Always-onを有効にしていればアンビエントモードで表示することができるようになります。

※詳細は [Supported functionality in the Maps API on Android Wear](https://developers.google.com/maps/documentation/android-api/wear#supported_functionality_in_the_maps_api_on_android_wear) を参照。

## Google Maps API on Android Wearの実装

### 導入

新規プロジェクトを作成する場合は、 *Add an activity to Wear* の画面で *Google Maps Wear Activity* を選択すると、あとはAPIキーを追加するだけで動作するWearableアプリがセットアップされて便利です。

その中のAPIの導入部分をbuild.gradleから抜粋すると次のようになります。

``` groovy:build.gradle
dependencies {
    compile "com.google.android.support:wearable:1.3.0"
    compile "com.google.android.gms:play-services-wearable:8.1.0"
    compile "com.google.android.gms:play-services-maps:8.1.0"
	
	// アンビエントモードを有効にする場合は必要
    provided 'com.google.android.wearable:wearable:1.0.0'
}
```

Wear側でのGoogle Play ServicesのMapsモジュールを追加するだけです。

### 実装

実装はGoogle Maps API for Androidと同じ流れになります。
マニフェストファイルは、本体がGoogle Play Servicesになると思われるので、最低限のパーミッションだけで済むようです。

``` xml:AndroidManifest.xml
<manifest>
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality.
    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	
	<!-- アンビエントモードを有効にする場合は必要 -->
	<uses-permission android:name="android.permission.WAKE_LOCK" />
	
	<application>
		<meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
	</application>
</manifest>
```

``` xml:activity_maps.xml
<FrameLayout
    android:id="@+id/map_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.MapFragment"
        app:ambientEnabled="true" />
        <!-- ↑アンビエントモードを有効にする場合は必要（コードでも可） -->
        
</FrameLayout>
```

``` java:MapsActivity.java
/** {@inheritDoc} */
@Override
public void onCreate(Bundle savedState) {
    // Obtain the MapFragment and set the async listener to be notified when the map is ready.
    mMapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
    mMapFragment.getMapAsync(this);
}

/** {@inheritDoc} */
@Override
public void onMapReady(GoogleMap googleMap) {
    // Add a marker in Sydney, Australia and move the camera.
    LatLng sydney = new LatLng(-34, 151);
    googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

    // UIの設定
    final UiSettings uiSettings = googleMap.getUiSettings();
    uiSettings.setZoomControlsEnabled(true);
    uiSettings.setCompassEnabled(true);
    googleMap.setMyLocationEnabled(true);
    // Indoorマップを有効にする
    googleMap.setIndoorEnabled(true);
}
```

このようにすることでこのように表示されます。

![Google Maps API on Android Wear 1](http://i.imgur.com/u3UOwVF.png)

HandheldとWearのデータの同期などなどライブラリが全部やってくれるので、Andoid Wearでもお手軽にGoogle Mapsと連携できるのは嬉しいですね。
しかし、上記のようにUI設定をもりもりしてしまうと画面が窮屈になってしまうので、用途に合わせて最小限に抑えるのがよさそうです。

アンビエントモードは確認できていないので略。

## 注意点

Andorid WearでGoogle Mapsを使用する上で注意する点は、画面の終了方法です。
通常、左へスワイプすると画面を終了することができるのですが、
MapFragmentを使用しているとこの動作が無効になり、スワイプで終了できません（ブログにそのことが書いてあります）。
Google Mapsアプリはできるのですが、APIでは無効にされているようです。

そこでブログで提案されていたのが、地図を長押ししてDismisOverlayViewを表示する方法で、このように表示されます。

![Imgur](http://i.imgur.com/fgTT0gk.png)

地図の長押しはマーカーの追加というイメージがあるので、個人的にはこの動作は慣れがいるなぁと思います。

代替案として、表示するUIが少ない場合は、Google Mapsアプリの用に画面下部にGoogle Mapsアプリと同じような「×」ボタンを置いてもいいのではないかとも思います。

![Imgur](http://i.imgur.com/MgmwhCu.png)

上記の例だとやり過ぎになってしまうので、ロケーションと×ボタンくらいならいけるのではないでしょうか。
（スタイルはもう少し統一しなければいけませんが）
Google Mapsアプリと同じように地図をタップしたらボタンが自動的に表示/非表示切り替わると助かるのですがね〜

以上、簡単ですがAPIの使い方でした。


> Written with [StackEdit](https://stackedit.io/).