Android:LocationManager vs谷歌Play服务

Android:LocationManager vs谷歌Play服务,android,gps,geolocation,Android,Gps,Geolocation,我想构建一个以获取用户当前位置为中心的应用程序,然后通过Google Places API查找用户附近的兴趣点(如酒吧、餐厅等) 在网上搜索开始的地方时,我遇到了一些使用LocationManager类的教程,还有一些使用Google Play Services查找用户位置的教程 乍一看,他们都做同样的事情,但由于我是新手,我有点困惑,我不知道哪种方法最适合我的需要。所以,我想问你: 这两种查找位置的方法(如果有)有什么区别?您应该使用Google Play Services位置api而不是Lo

我想构建一个以获取用户当前位置为中心的应用程序,然后通过Google Places API查找用户附近的兴趣点(如酒吧、餐厅等)

在网上搜索开始的地方时,我遇到了一些使用
LocationManager
类的教程,还有一些使用Google Play Services查找用户位置的教程

乍一看,他们都做同样的事情,但由于我是新手,我有点困惑,我不知道哪种方法最适合我的需要。所以,我想问你:


这两种查找位置的方法(如果有)有什么区别?您应该使用Google Play Services位置api而不是LocationManager。根据文件:

Google Play服务位置API优于Android 框架位置API(android.location)作为添加位置的一种方式 对你的应用程序的感知。如果您当前正在使用Android 框架位置API,强烈建议您切换到 谷歌播放服务位置API尽快

至于为什么要切换,谷歌表示:

谷歌定位服务API,谷歌Play服务的一部分, 提供了一个更强大的高级框架,可以自动 处理位置提供程序、用户移动和位置准确性。信息技术 还处理基于功耗的位置更新调度 您提供的参数。在大多数情况下,你会得到更好的电池 通过使用 位置服务API


Android上的用户位置

在Android上获取用户的位置比在iOS上要简单一些。首先,有两种完全不同的方法可以做到这一点。第一种是使用来自
Android.location.LocationListener
的Android API,第二种是使用Google Play Services API
com.Google.Android.gms.location.LocationListener
。让我们把它们都看一遍

  • Android的位置API

    Android的位置API使用三种不同的提供者来获取位置-

    • LocationManager.GPS\U提供程序
      -此提供程序使用卫星确定位置。根据情况,此提供程序可能需要一段时间才能返回位置修复
    • LocationManager.NETWORK\u提供商
      -该提供商根据基站和WiFi接入点的可用性确定位置。通过网络查找检索结果
    • LocationManager.PASSIVE\u提供程序
      -此提供程序将返回由其他提供程序生成的位置。当其他应用程序或服务请求位置更新时,您被动地接收位置更新,而不是自己实际请求位置
  • 其要点是从系统中获取
    LocationManager
    的对象,实现
    LocationListener
    ,并在
    LocationManager
    上调用
    requestLocationUpdates

    下面是一段代码片段:

        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    // Define a listener that responds to location updates
    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
          // Called when a new location is found by the network location provider.
          makeUseOfNewLocation(location);
        }
    
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    
        public void onProviderEnabled(String provider) {}
    
        public void onProviderDisabled(String provider) {}
      };
    
    // Register the listener with the Location Manager to receive location updates
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    
    很好地解释了代码。但他们也提到,在大多数情况下,你会得到更好的电池性能,以及更适当的准确性,而不是使用。现在混乱开始了

  • 谷歌的定位服务API
  • Google的位置服务API是Google Play Services APK()的一部分。它们构建在Android的API之上。这些API提供了“融合位置提供程序”,而不是上述提供程序。此提供程序会根据准确性、电池使用情况等自动选择要使用的底层提供程序。它的速度很快,因为您可以通过不断更新的系统范围服务获取位置。您还可以使用更高级的功能,如地理围栏

    要使用Google的定位服务,您的应用程序需要连接到
    GooglePlayServicesClient
    。要连接到客户端,您的活动(或片段等)需要实现
    GooglePlayServicesClient.ConnectionCallbacks
    GooglePlayServicesClient.OnConnectionFailedListener
    接口。 下面是一个示例代码:

        public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
        LocationClient locationClient;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my);
            locationClient = new LocationClient(this, this, this);
        }
    
        @Override
        public void onConnected(Bundle bundle) {
        Location location = locationClient.getLastLocation() ;
            Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onDisconnected() {
        Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            // code to handle failed connection
            // this code can be found here — http://developer.android.com/training/location/retrieve-current.html 
        }
    
    • 为什么
      locationClient.getLastLocation()为空
    locationClient.getLastLocation()
    从客户端获取最后一个已知位置。但是,如果至少有一个客户端连接到融合位置提供程序,则融合位置提供程序将仅维护后台位置。一旦第一个客户端连接,它将立即尝试获取位置。如果您的活动是第一个连接的客户端,并且您立即在
    onConnected()
    中调用
    getLastLocation()
    ,则可能没有足够的时间让第一个位置进入。这将导致
    location
    null

    要解决此问题,您必须(不确定地)等待提供者获取位置,然后调用
    getLastLocation()
    ,这是不可能知道的。另一个(更好的)选择是实现
    com.google.android.gms.location.LocationListener
    接口,以接收定期的位置更新(并在获得第一次更新后将其关闭)

    在这段代码中,您正在检查客户端是否已经拥有最后一个位置(在
    onConnected
    )。如果没有,则请求位置更新,并在获得更新后立即关闭请求(在
    onLocationChanged()
    callback中)

    注意,
    locationClient.requestLocationUpdates(locationRequest,this)
    必须位于
    onConnected
    回调中,否则您将获得
    IllegalStateException
    ,因为您将尝试在未连接到Google Play Services客户端的情况下请求位置

    • public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { // . . . . . . . . more stuff here LocationRequest locationRequest; LocationClient locationClient; @Override protected void onCreate(Bundle savedInstanceState) { // . . . . other initialization code locationClient = new LocationClient(this, this, this); locationRequest = new LocationRequest(); // Use high accuracy locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Set the update interval to 5 seconds locationRequest.setInterval(UPDATE_INTERVAL); // Set the fastest update interval to 1 second locationRequest.setFastestInterval(FASTEST_INTERVAL); } // . . . . . . . . other methods @Override public void onConnected(Bundle bundle) { Location location = locationClient.getLastLocation(); if (location == null) locationClient.requestLocationUpdates(locationRequest, this); else Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show(); } // . . . . . . . . other methods @Override public void onLocationChanged(Location location) { locationClient.removeLocationUpdates(this); // Use the location here!!! }
          LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
      if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
          locationEnabled = false;
          Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
      }
      else locationEnabled = true;
      
          if (location != null) {
          Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
      }
      else if (location == null && locationEnabled) {
          locationClient.requestLocationUpdates(locationRequest, this);
      }
      
      task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
      @Override
      public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
          // All location settings are satisfied. The client can initialize
          // location requests here.
          // ...
      }
      });
      
      task.addOnFailureListener(this, new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
              if (e instanceof ResolvableApiException) {
                  // Location settings are not satisfied, but this can be fixed
                  // by showing the user a dialog.
                  try {
                      // Show the dialog by calling startResolutionForResult(),
                      // and check the result in onActivityResult().
                      ResolvableApiException resolvable = (ResolvableApiException) e;
                      resolvable.startResolutionForResult(MainActivity.this,
                              REQUEST_CHECK_SETTINGS);
                  } catch (IntentSender.SendIntentException sendEx) {
                      // Ignore the error.
                  }
              }
          }
      });
      
        private FusedLocationProviderClient fusedLocationClient;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
      }