使融合位置提供程序LocationClient更易于使用

时间:2014-01-07 00:36:12

标签: android geolocation location google-play

假设我的应用中有5种不同的活动希望使用LocationClient.getLastLocation()来获取最后的已知位置。这看起来很简单。

理想情况下,我只想在每个活动中创建一个LocationClient并调用getLastLocation()。但是,要连接到Google Play服务还需要做一些额外的工作,例如致电LocationClient.connect()并处理onConnectedonDisconnectedonConnectionFailed回调。文档在这里:https://developer.android.com/training/location/retrieve-current.html

据我所知,我的五个不同活动中的每一个都必须处理LocationClient的生命周期方法。他们也无法立即在getLastLocation()中致电onCreate(),因为该活动的连接可能尚未确定。

是否有一种简单的方法可以简化LocationClient的生命周期,以便在我为我的应用建立一次连接后,getLastLocation()可以立即在任何新活动中使用?

4 个答案:

答案 0 :(得分:5)

我使用融合位置提供程序API来定期更新位置。我在后台服务中实现了它(例如LocationUpdateService extends Service)。之前我使用的是Android Location框架API,但它对电池使用效果不佳。融合位置提供商API是有效使用电池的最佳选择。

我还准备了实施它所需的步骤说明(以及其他有用信息)。简单来说,这是目前在Android平台上获取位置数据的最佳方式。 Google Play服务提供了许多位置API来获取位置数据(例如,用户的当前位置,或者您可以说是设备的最后已知位置)。

融合位置提供商是Google Play服务中的位置API之一。 这些是先决条件:

  1. Google Play服务SDK用作库项目(并且Google PlayService也已正确安装在您的设备中)。

    • 从SDK Manager下载并安装Google Play服务组件,并将该库添加到您的项目中。
    • 将您的开发项目中的GooglePlayServices库从android google-play-services_lib导入为Library项目。
  2. 您应该拥有一个实际设备,因为此API无法在模拟器中使用。

  3. 融合位置提供商智能地管理基础定位技术(GPS / Wi-Fi /网络提供商的连接),并根据我们的需求为我们提供最佳位置。

    为什么要使用它

    我们可以选择其中一个位置提供商(网络或GPS)并请求位置更新或设置近距离警报。但这种方法存在两个主要问题: 1.如果我们需要定义精确的位置,我们必须在网络和GPS位置提供商之间切换(因为GPS不能在室内工作)。 2.接近警报用于通知用户某个位置的接近程度,这对电池寿命造成了影响。

    优势

    1. 简单的API:它让我们指定高级别需求,如“高精度”或“低功耗”,而不必担心位置提供商。
    2. 电池效率:它可以最大限度地降低应用功耗。基于所有传入的位置请求和可用的传感器,融合位置提供商选择最有效的方式来满足这些需求。
    3. 使用此API的步骤:

      1. 在清单文件中声明与位置相关的权限。

        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        

        或者

        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        
      2. 实现相关接口和回调。在我们请求位置更新之前,我们必须首先实现位置服务用于向我们的应用程序传达连接状态的接口:

        • com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks:指定位置客户端连接或断开连接时Location Services调用的方法。
        • com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener
      3. 连接到Google Play服务,将LocationClient与Google API相关联。为此,请创建LocationClient对象(GoogleApiClient的实例):

        mLocationClient = new GoogleApiClient.Builder(getApplicationContext())
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
        

        然后拨打mLocationClient.connect();

      4. 使用FusedLocationProviderApi类创建LocationServices的实例:

        private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
        
      5. 检索onConnected(Bundle bundle)中的当前位置:

        Location currentLocation = fusedLocationProviderApi                                  .getLastLocation(mLocationClient);
        if (mCurrentLocation != null) {
            Log.d(TAG, "last location = " + mCurrentLocation.getLatitude() +
                " - " + mCurrentLocation.getLongitude());
        }           
        
      6. 创建并设置LocationRequest对象:

        mLocationRequest = new LocationRequest();
        
        private void setLocationParameter() {
            // Set the update interval
            mLocationRequest.setInterval(Constants.SECONDS_TO_UP);
            // Use high accuracy
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            // Set the interval ceiling to one minute
            mLocationRequest.setFastestInterval(Constants.SECONDS_TO_UP);
            // Set the distance to 10 meters.
            mLocationRequest.setSmallestDisplacement(Constants.METERS_TO_UP);
        }
        
      7. 要从位置服务获取定期位置更新,我们会使用位置客户端发送请求。

        LocationListener listener =  new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {    
                Utils.locationUpdates = Utils.locationUpdates + 1;
                if (Utils.locationUpdates == 1) {
                    mLocationRequest .setPriority(LocationRequest.PRIORITY_LOW_POWER);
                    LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest, listener);
                }
            }
        };
        

答案 1 :(得分:2)

您可以创建服务以在后台处理融合位置提供程序,并将位置和状态广播到您的活动。请参阅链接https://gist.github.com/blackcj/20efe2ac885c7297a676

答案 2 :(得分:1)

您可以创建一个实现所有这些方法的基本活动,然后您的所有活动只需要扩展它。

供参考检查:android how to create my own Activity and extend it?

答案 3 :(得分:1)

如果您熟悉反应式编程,则必须尝试RxLocation库,该库将Fused API包装为RX方式。

示例:

// Create one instance and share it
RxLocation rxLocation = new RxLocation(context);

LocationRequest locationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(5000);

rxLocation.location().updates(locationRequest)
        .flatMap(location -> rxLocation.geocoding().fromLocation(location).toObservable())
        .subscribe(address -> {
            /* do something */
        });