Skip to content

Most visited

Recently visited

navigation

在 Android Wear 上检测位置

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

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

本文介绍如何检查手表内置位置传感器、如何接收位置数据以及如何监控绑定的数据连接。另请参阅与 iPhone 配对的手表的位置数据

:本文假设您了解如何使用 Google Play Services API 检索位置数据

使用 Fused Location Provider

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

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

检测板载 GPS

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

要确定手表是否带有内置 GPS 传感器,可使用 hasSystemFeature() 函数。以下代码可在您启动某个 Activity 时检测手表是否带有内置 GPS 传感器:

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);
}

处理断开连接 Event

如果手表没有内置 GPS 传感器,则当手表与手机的绑定数据连接断开时,手表的位置数据流将会突然断开。如果您的应用需要不间断的数据流,您的应用必须检测连接是否断开,向用户发出警告,然后妥善地降级功能。

要检测绑定的数据连接是否断开,请使用 NodeApi GetConnectedNodesResult 函数。例如:

  1. 初始化 GoogleApiClient 并创建一个调用 NodeApi 的函数,例如,一个名为 inspectNodes 的函数:
    private GoogleApiClient mGoogleApiClient;
    private boolean mWearableConnected = false;
    
    @Override
    public void onCreate() {
        super.onCreate();
    
        mGoogleApiClient = 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(mGoogleApiClient).setResultCallback(this, 1000, TimeUnit.MILLISECONDS);
    }
    
  2. 使用以下回调函数获取 inspectNodes 函数的输出结果:
    @Override
    public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
        if (getConnectedNodesResult != null && getConnectedNodesResult.getNodes() != null){
            mWearableConnected = false;
            for (Node node : getConnectedNodesResult.getNodes()){
                if (node.isNearby()){
                    mWearableConnected = true;
                }
            }
        }
        Log.v("TEST", "mWearableConnected: " + mWearableConnected);
    }
    

处理未找到位置事件

当 GPS 信号断开时,您可以检索用户手表的最近已知位置。当您无法修复 GPS 连接,或者手表没有内置 GPS 并与手机断开连接时,检索最近已知位置会很有帮助。如需了解详细信息,请参阅获取最近已知位置

同步数据

如果您的手表应用使用内置 GPS 传感器记录数据,则您可能需要与手持式设备同步位置数据。借助 LocationListener,您可实现 onLocationChanged() 函数以检测和记录位置的变化情况。

适用于手表应用的以下代码可检测位置在何时发生变化,并使用 Data Layer API 存储数据,以供您的手机应用日后检索之用:

@Override
public void onLocationChanged(Location location) {
    ...
    addLocationEntry(location.getLatitude(), location.getLongitude());
}

private void addLocationEntry(double latitude, double longitude) {
    if (!mSaveGpsLocation || !mGoogleApiClient.isConnected()) {
        return;
    }

    mCalendar.setTimeInMillis(System.currentTimeMillis());

    // Set the path of the data map
    String path = Constants.PATH + "/" + mCalendar.getTimeInMillis();
    PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(path);

    // Set the location values in the data map
    putDataMapRequest.getDataMap()
            .putDouble(Constants.KEY_LATITUDE, latitude);
    putDataMapRequest.getDataMap()
            .putDouble(Constants.KEY_LONGITUDE, longitude);
    putDataMapRequest.getDataMap()
            .putLong(Constants.KEY_TIME, mCalendar.getTimeInMillis());

    // Prepare the data map for the request
    PutDataRequest request = putDataMapRequest.asPutDataRequest();

    // Request the system to create the data item
    Wearable.DataApi.putDataItem(mGoogleApiClient, request)
            .setResultCallback(new ResultCallback() {
                @Override
                public void onResult(DataApi.DataItemResult dataItemResult) {
                    if (!dataItemResult.getStatus().isSuccess()) {
                        Log.e(TAG, "Failed to set the data, "
                                + "status: " + dataItemResult.getStatus()
                                .getStatusCode());
                    }
                }
            });
}

如需了解如何使用 Data Layer API 的详细信息,请参阅发送和同步数据

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)