在 Wear OS 上检测位置

手表小巧、一览无余的外形特征使得 Wear OS by Google 谷歌成为面向记录、报告和响应用户位置的应用的理想平台。例如,您可以构建应用,为用户提供其运动距离、速度和方向的实时更新信息,或者提供一览无余的用户周边位置队列。

有些手表带有内置 GPS 传感器,可直接检索位置数据,而无需共享网络的手机。不过,当您在手表应用中请求位置数据时,您不必担心位置数据的来源;系统使用最节能的方法获取数据。然而,正如以下几节中介绍的那样,您的应用需要解决位置数据丢失的问题。

建议您使用 Fused Location Provider 在手表上获取位置数据。此外,本文档还介绍了如何检查手表上的位置传感器、接收位置数据和监控共享网络的数据连接。另请参阅与 iPhone 配对的手表的位置数据

为降低位置数据获取对电池续航时间造成的不良影响,您应该确保应用调用设为 PRIORITY_BALANCED_POWER_ACCURACYsetPriority()。您应该使用 setInterval() 确保请求位置数据的频率不超过每分钟一次。

注意:本文档假定您知道如何使用 Google Play Services API 检索位置数据

使用 Fused Location Provider

在手表上,您应使用 FusedLocationProviderApi (FLP) 获取位置数据。如果手表不带 GPS 传感器,FLP 将会自动使用手机提供的位置数据。 如需了解详细信息,请参阅创建位置信息服务客户端

有关如何请求位置更新和持续跟踪用户位置的信息,请参阅接收位置更新

检测内置 GPS

如果用户佩戴未内置 GPS 传感器的手表出去慢跑,但却忘记携带与之配对的手机,您的手表应用将无法通过共享网络的连接获取位置数据。您的应用应检测位置并警告用户位置功能不可用。

要确定手表是否带有内置 GPS 传感器,可使用 hasSystemFeature() 方法。以下代码可在您启动某个 Activity 时检测手表是否带有内置 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 并与手机断开连接时,检索最近已知位置会很有帮助。如需了解详细信息,请参阅获取最近已知位置