Wear OS におけるロケーション検出

時計は、小さくて一目で見ることができるフォーム ファクタです。そのため、Wear OS by Google は、ユーザーのロケーションの記録や報告を行ったり、それに反応したりするアプリの理想的なプラットフォームになっています。たとえば、ユーザーに距離、速度、方向をリアルタイムに知らせるアプリや、ユーザーの周辺について一目でわかるキューを提供するアプリを構築することができます。

以下の関連リソースもご覧ください。

時計の中には、ビルトインの GPS センサーが搭載されており、ペア設定されたスマートフォンがなくてもロケーション データを取得できるものがあります。しかし、時計のアプリからロケーション データをリクエストする場合は、どこから来るロケーション データであるかを気にする必要はありません。システムは、もっとも電源効率がよい方法でデータを取得してくれます。ただし、以下のセクションで説明するように、アプリはロケーション データの喪失に対処する必要があります。

時計でロケーション データを取得する際に推奨される方法は、融合された位置予測プロバイダの使用です。また、このドキュメントでは、時計に搭載されたロケーション センサーの確認方法、ロケーション データの受信方法、ペア設定によるデータ接続の監視方法についても説明します。iPhone とペア設定された時計のロケーション データもご覧ください。

ロケーション データの取得による電池寿命への悪影響を減らすため、アプリで setPriority() を呼び出して PRIORITY_BALANCED_POWER_ACCURACY を設定していることを確認してください。1 分に 1 回を超える頻度でロケーションを取得しないように、setInterval() を使って制御する必要があります。

注: このドキュメントは、Google Play Services API を使ったロケーション データの取得方法について知識があることを前提としています。

融合された位置予測プロバイダの利用

時計では、 FusedLocationProviderApi(FLP)を使ってロケーション データを取得する必要があります。時計に GPS センサーがない場合、FLP は自動的にスマートフォンのロケーション データを使用します。詳細については、ロケーション サービス クライアントの作成をご覧ください。

ロケーションのアップデートをリクエストする方法や、ユーザーのロケーションを継続的にトラッキングする方法の詳細については、ロケーションのアップデートの受信をご覧ください。

オンボード GPS の検出

ユーザーがビルトイン GPS センサーが搭載されていない時計を着け、ペア設定されたスマートフォンを忘れてジョギングに出かけた場合、時計のアプリは、ペア設定された接続を通してロケーション データを取得することができません。アプリはこの状況を検出し、ロケーション機能が利用できないことをユーザーに警告する必要があります。

時計にビルトイン GPS センサーが搭載されているかを判断するには、hasSystemFeature() メソッドを使います。次のコードは、アクティビティを開始した際に、時計にビルトイン GPS センサーが搭載されているかを検出します。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main_activity)

    if (!hasGps()) {
        Log.d(TAG, "This hardware doesn't have GPS.")
        // Fall back to functionality that does not use location or
        // warn the user that location function is not available.
    }
}

private fun hasGps(): Boolean =
        packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)

Java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    if (!hasGps()) {
        Log.d(TAG, "This hardware doesn't have GPS.");
        // Fall back to functionality that does not use location or
        // warn the user that location function is not available.
    }

    ...
}

private boolean hasGps() {
    return getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS);
}

切断イベントの処理

時計にビルトイン GPS センサーが搭載されていない場合、ペア設定されたスマートフォンとのデータ接続が失われると、ロケーションのデータ ストリームが突然失われることになります。恒常的なデータのストリームが必要なアプリでは、接続が失われたことを検出し、ユーザーに警告して、スムーズな形で機能を停止する必要があります。

ペア設定されたデータ接続が失われたことを検出するには、 NodeApiGetConnectedNodesResult メソッドを使います。次に例を示します。

  1. GoogleApiClient を初期化し、NodeApi を呼び出すメソッド(例: inspectNodes という名前のメソッド)を作成します。

    Kotlin

    private lateinit var googleApiClient: GoogleApiClient
    private var wearableConnected = false
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        googleApiClient = GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
                    override fun onConnected(connectionHint: Bundle?) {
                        inspectNodes()
                    }
    
                    override fun onConnectionSuspended(cause: Int) {}
                })
                .build()
    
    }
    
    private fun inspectNodes() {
        Wearable.NodeApi
                .getConnectedNodes(googleApiClient)
                .setResultCallback(this, 1000, TimeUnit.MILLISECONDS)
    }
    

    Java

    private GoogleApiClient googleApiClient;
    private boolean wearableConnected = false;
    
    @Override
    public void onCreate() {
        super.onCreate();
    
        googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(Bundle connectionHint) {
                        inspectNodes();
                    }
    
                    @Override
                    public void onConnectionSuspended(int cause) {
                    }
                })
                .build();
    }
    
    private void inspectNodes(){
        Wearable.NodeApi.getConnectedNodes(googleApiClient).setResultCallback(this, 1000, TimeUnit.MILLISECONDS);
    }
    
  2. 次のコールバック メソッドを利用して、inspectNodes メソッドの結果を取得します。

    Kotlin

    override fun onResult(getConnectedNodesResult: NodeApi.GetConnectedNodesResult) {
        wearableConnected = false
        getConnectedNodesResult.nodes.forEach { node ->
            wearableConnected = wearableConnected or node.isNearby
        }
        Log.v("TEST", "wearableConnected: $wearableConnected")
    }
    

    Java

    @Override
    public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
        if (getConnectedNodesResult != null && getConnectedNodesResult.getNodes() != null){
            wearableConnected = false;
            for (Node node : getConnectedNodesResult.getNodes()){
                if (node.isNearby()){
                    wearableConnected = true;
                }
            }
        }
        Log.v("TEST", "wearableConnected: " + wearableConnected);
    }
    

ロケーションが見つからない場合の処理

GPS 信号が失われた場合、ユーザーの時計での最後の既知のロケーションを取得することができます。最後の既知のロケーションを取得すると、GPS の問題を修正できない場合や、ビルトイン GPS がない時計でスマートフォンとの接続が失われた場合に役立ちます。詳細については、既知の最後のロケーションの取得をご覧ください。