Skip to content

Most visited

Recently visited

navigation

在 Android Wear 上检测位置

手表的位置检测功能让应用的用户可以更好地了解其所在的地理位置、移动情况以及周围环境。借助穿戴式设备体型小巧和一目了然的特点,您可以构建记录和响应位置数据的易用型应用。

有些穿戴式设备包含一个 GPS 传感器,它可检索位置数据,而无需绑定另一个设备。不过,当您在穿戴式设备应用中请求位置数据时,您不必担心位置数据的来源;系统使用最节能的方法检索位置更新。在穿戴式设备本身没有内置 GPS 传感器的情况下,即便与其配对设备的连接被断开,您的应用也应能够处理丢失位置数据的情况。

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

:本文假设您了解如何使用 Google Play services API 检索位置数据。如需了解详细信息,请参阅让您的应用能够感知位置

连接至 Google Play 服务

通过 Google Play services location API 获取穿戴式设备的位置数据。您可使用 FusedLocationProviderApi 及其伴生类来获取该数据。要访问位置服务,请创建一个 GoogleApiClient 实例,该实例是任何 Google Play Services API 的主要入口点。

注意:请勿使用 Android 框架中的现有 Location API。检索位置更新的最佳做法是通过 Google Play services API 进行检索,如本文所述。

要连接至 Google Play 服务,请配置您的应用以创建一个 GoogleApiClient 实例:

  1. 创建一个操作组件,用于指定接口 ConnectionCallbacksOnConnectionFailedListenerLocationListener 的实现。
  2. 在您的操作组件的 onCreate() 函数中,创建一个 GoogleApiClient 实例并添加位置服务。
  3. 要妥善管理连接的生命周期,在 onResume() 函数中调用 connect(),同时在 onPause() 函数中调用 disconnect()

以下代码示例展示了如何实现用于实现 LocationListener 接口的操作组件:

public class WearableMainActivity extends Activity implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

    private GoogleApiClient mGoogleApiClient;
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ...
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addApi(Wearable.API)  // used for data layer API
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGoogleApiClient.connect();
        ...
    }

    @Override
    protected void onPause() {
        super.onPause();
        ...
        mGoogleApiClient.disconnect();
    }
}

如需了解连接至 Google Play 服务的详细信息,请参阅访问 Google API

请求位置更新

在您的应用连接至 Google Play Services API 后,它随时可以开始接收位置更新。当系统为您的客户端调用 onConnected() 回调时,您可按如下方法构建位置数据请求:

  1. 创建一个 LocationRequest 对象并使用 setPriority() 等函数设置任意选项。
  2. 使用 requestLocationUpdates() 请求位置更新。
  3. onPause() 函数中使用 removeLocationUpdates() 移除位置更新。

以下示例展示如何检索和移除位置更新:

@Override
public void onConnected(Bundle bundle) {
    LocationRequest locationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(UPDATE_INTERVAL_MS)
            .setFastestInterval(FASTEST_INTERVAL_MS);

    LocationServices.FusedLocationApi
            .requestLocationUpdates(mGoogleApiClient, locationRequest, this)
            .setResultCallback(new ResultCallback() {

                @Override
                public void onResult(Status status) {
                    if (status.getStatus().isSuccess()) {
                        if (Log.isLoggable(TAG, Log.DEBUG)) {
                            Log.d(TAG, "Successfully requested location updates");
                        }
                    } else {
                        Log.e(TAG,
                                "Failed in requesting location updates, "
                                        + "status code: "
                                        + status.getStatusCode()
                                        + ", message: "
                                        + status.getStatusMessage());
                    }
                }
            });
}

@Override
protected void onPause() {
    super.onPause();
    if (mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi
             .removeLocationUpdates(mGoogleApiClient, this);
    }
    mGoogleApiClient.disconnect();
}

@Override
public void onConnectionSuspended(int i) {
    if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "connection to location client suspended");
    }
}

现在,您已启用位置更新,系统将以在 setInterval() 中指定的间隔调用 onLocationChanged() 函数及更新的位置。

检测板载 GPS

并非所有穿戴式设备都带有 GPS 传感器。如果您的用户出去跑步并将手机放在家里,您的穿戴式设备应用将无法通过绑定的连接接收位置数据。如果穿戴式设备没有传感器,您应检测到此情况,并警告用户位置功能不可用。

要确定您的 Android Wear 设备是否具有内置 GPS 传感器,请使用 hasSystemFeature() 函数。在您启动某个操作组件时,可通过以下代码检测设备是否具有内置 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);
}

处理断开连接事件

依赖于绑定连接获取位置数据的穿戴式设备可能会突然失去其连接。如果您的穿戴式设备应用期望获得稳定的数据流,那么,您必须根据数据在何处中断或不可用来处理连接断开事件。在没有板载 GPS 传感器的穿戴式设备上,当设备丢失其绑定的数据连接时会出现位置数据丢失的情况。

如果您的应用依赖于绑定数据连接获取位置数据且穿戴式设备没有 GPS 传感器,那么,您应检测该连接是否已断开,警告用户并妥善降级您的应用功能。

要检测绑定的数据连接是否断开,请:

  1. 扩展一个 WearableListenerService,其允许您侦听重要的数据层事件。
  2. 在您的 Android 清单中声明一个 Intent 过滤器,以向系统通知您的 WearableListenerService。此过滤器允许系统根据需要绑定您的服务。
    <service android:name=".NodeListenerService">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
        </intent-filter>
    </service>
    
  3. 实现 onPeerDisconnected() 函数并处理设备是否具有内置 GPS 的情况。
    public class NodeListenerService extends WearableListenerService {
    
        private static final String TAG = "NodeListenerService";
    
        @Override
        public void onPeerDisconnected(Node peer) {
            Log.d(TAG, "You have been disconnected.");
            if(!hasGPS()) {
                // Notify user to bring tethered handset
                // Fall back to functionality that does not use location
            }
        }
        ...
    }
    
如需了解详细信息,请阅读侦听数据层事件指南。

处理未找到位置事件

当 GPS 信号丢失时,您仍可以使用 getLastLocation() 检索上一个已知位置。当您无法修复 GPS 连接,或者您的穿戴式设备没有内置 GPS 并与手机断开连接时,此方法会很有帮助。

以下代码使用 getLastLocation() 检索上一个已知位置(如果可用):

Location location = LocationServices.FusedLocationApi
                .getLastLocation(mGoogleApiClient);

同步数据

如果您的穿戴式设备应用使用内置 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!

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.
(Sep 2017 survey)