Android:LocationManager与Google Play服务 [英] Android : LocationManager vs Google Play Services

查看:109
本文介绍了Android:LocationManager与Google Play服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个以获取用户当前位置为中心的应用程序,然后通过 Google Places API 。

在网络搜索地点开始时,我遇到了一些使用 LocationManager 类和其他一些教程的教程使用 Google Play服务来查找用户的位置。



第一眼看到他们两个人都做同样的事情,但是因为我是新的这个我有点困惑,我不知道哪种方法最适合我的需求。所以,我想问你:

这两种查找位置的方法(如果有的话)有什么区别? p>

解决方案

Android上的用户位置 用户在Android上的位置比在iOS上稍微简单一点。要开始混淆,有两种完全不同的方式可以做到这一点。第一种是使用来自 android.location.LocationListener 的Android API,第二种是使用Google Play服务API com.google.android.gms.location .LocationListener 。我们来看看它们两个。


  1. Android的位置API

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


    • LocationManager.GPS_PROVIDER - 此提供商使用卫星确定位置。根据条件,此提供商可能需要一段时间才能返回位置信息。

    • LocationManager.NETWORK_PROVIDER - 此提供商根据手机塔和WiFi接入点的可用性。通过网络查询检索结果。

    • LocationManager.PASSIVE_PROVIDER - 此提供商将返回由其他提供商生成的位置。您在被其他应用程序或服务请求时被动接收位置更新,而无需亲自实际请求位置。
    • b

      它的要点是你从系统中获得一个 LocationManager 对象,实现 LocationListener ,并在 LocationManager 上调用 requestLocationUpdates



      一个代码片段:

        LocationManager locationManager =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE); 
      //定义响应位置更新的侦听器
      LocationListener locationListener = new LocationListener(){
      public void onLocationChanged(Location location){
      //当新位置由网络位置提供商发现。
      makeUseOfNewLocation(location);

      $ b $ public void onStatusChanged(String provider,int status,Bundle extras){}
      $ b $ public void onProviderEnabled(String provider){}

      public void onProviderDisabled(String provider){}
      };

      //使用位置管理器注册侦听器以接收位置更新
      locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,locationListener);

      很好地解释了代码。但他们也提到,在大多数情况下,通过使用 Google位置服务API Google的位置服务API

Google的位置服务API是Google Play服务APK的一部分(如何设置)。它们建立在Android的API之上。这些API提供Fused Location Provider而不是上述提供者。根据准确性,电池使用情况等,此提供商自动选择要使用的底层提供商。它速度很快,因为您可以从系统级服务获取位置信息并不断更新。您可以使用更多高级功能,例如geofencing。



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

  public class MyActivity extends Activity实现了ConnectionCallbacks,OnConnectionFailedListener {
LocationClient locationClient;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
locationClient = new LocationClient(this,this,this);

$ b @Override
public void onConnected(Bundle bundle){
Location location = locationClient.getLastLocation();
Toast.makeText(这个连接到Google Play服务,Toast.LENGTH_SHORT).show();

$ b @Override
public void onDisconnected(){
Toast.makeText(这是从Google Play服务连接,Toast.LENGTH_SHORT).show ();
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult){
//处理失败连接的代码
//此代码可以在这里找到 - http://developer.android.com/training/location/retrieve-current.html
}




  • 为什么 locationClient.getLastLocation() null?



locationClient.getLastLocation()从客户端获取最后一个已知位置。但是,如果至少有一个客户端连接到位置,Fused Location Provider将仅保留后台位置。一旦第一个客户端连接,它将立即尝试获得一个位置。如果您的活动是第一个连接的客户端,并且您立即在 onConnected()中调用 getLastLocation(),那可能会没有足够的时间让第一个地点进入。这会导致位置 null



为了解决这个问题,你必须等待(不确定地),直到提供者获得位置,然后调用 getLastLocation(),这是不可能知道的。另一个(更好的)选项是实现 com.google.android.gms.location.LocationListener 界面以接收定期位置更新(并在您获得第一次更新后关闭它)。

  public class MyActivity extends Activity实现了ConnectionCallbacks,OnConnectionFailedListener,LocationListener {
//。 。 。 。 。 。 。 。更多的东西在这里
LocationRequest locationRequest;
LocationClient locationClient;

@Override
保护无效的onCreate(Bundle savedInstanceState){
//。 。 。 。其他初始化代码
locationClient = new LocationClient(this,this,this);
locationRequest = new LocationRequest();
//使用高精度
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//将更新间隔设置为5秒
locationRequest.setInterval(UPDATE_INTERVAL);
//设置最快更新间隔为1秒
locationRequest.setFastestInterval(FASTEST_INTERVAL);
}
//。 。 。 。 。 。 。 。其他方法
@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();
}
//。 。 。 。 。 。 。 。其他方法
@Override
public void onLocationChanged(Location location){
locationClient.removeLocationUpdates(this);
//使用位置在这里!





$ b

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



请注意, locationClient.requestLocationUpdates(locationRequest,this); 必须位于 onConnected 回调,否则你将得到一个 IllegalStateException ,因为你将尝试请求没有连接到Google Play服务客户端的位置。




  • 用户已停用定位服务



很多时候,用户会禁用位置服务(以节省电池或隐私原因)。在这种情况下,上面的代码仍然会请求位置更新,但 onLocationChanged 永远不会被调用。您可以通过检查用户是否已禁用位置服务来停止请求。



如果您的应用要求他们启用位置服务,则您希望显示一条消息或一条消息敬酒。不幸的是,无法检查用户是否在Google的位置服务API中禁用了位置服务。为此,您将不得不诉诸于Android的API。



在您的 onCreate 方法中:

  LocationManager管理器=(LocationManager)getActivity()。getSystemService(Context.LOCATION_SERVICE); 
if(!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)&&!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
locationEnabled = false;
Toast.makeText(getActivity(),为精确数据启用位置服务,Toast.LENGTH_SHORT).show();
}
else locationEnabled = true;

然后在 locationEnabled code> onConnected 方法如下:

  if(location!= null){
Toast.makeText(getActivity(),Location:+ location.getLatitude()+,+ location.getLongitude(),Toast.LENGTH_SHORT).show();
}
else if(location == null&& locationEnabled){
locationClient.requestLocationUpdates(locationRequest,this);
}

感谢 Rahul Jiresal


I want to build an app that centers around getting the user's current location and then find points of interest(such as bars,restaurants,etc) that are close to him/her via the Google Places API.

Upon searching the web for a place to start I came across some tutorials that use the LocationManager class and some others that use Google Play Services in order to find the users location.

On first sight both of them do the same thing, but since I am new to this I got a little confused and I don't know which method suits my needs the best. So, I want to ask you :

What are the differences between these two methods of finding locations (if there are any) ?

解决方案

User Location on Android

Getting the user’s location on Android is a little less straightforward than on iOS. To start the confusion, there are two totally different ways you can do it. The first is using Android APIs from android.location.LocationListener, and the second is using Google Play Services APIs com.google.android.gms.location.LocationListener. Let’s go through both of them.

  1. Android’s Location API

    The Android’s location APIs use three different providers to get location -

    • LocationManager.GPS_PROVIDER — This provider determines location using satellites. Depending on conditions, this provider may take a while to return a location fix.
    • LocationManager.NETWORK_PROVIDER — This provider determines location based on availability of cell tower and WiFi access points. Results are retrieved by means of a network lookup.
    • LocationManager.PASSIVE_PROVIDER — This provider will return locations generated by other providers. You passively receive location updates when other applications or services request them without actually requesting the locations yourself.

The gist of it is that you get an object of LocationManager from the system, implement the LocationListener, and call the requestLocationUpdates on the LocationManager.

Here’s a code snippet:

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

Google’s API Guide on Location Strategies explains the code pretty nicely. But they also mention that in most cases, you’ll get better battery performance, as well as more appropriate accuracy, by using the Google Location Services API instead. Now the confusion starts!

  1. Google’s Location Services API

Google’s Location Services API is a part of the Google Play Services APK (here’s how to set it up) . They’re built on top of Android’s API. These APIs provide a "Fused Location Provider" instead of the providers mentioned above. This provider automatically chooses what underlying provider to use, based on accuracy, battery usage, etc. It is fast because you get location from a system-wide service that keeps updating it. And you can use more advanced features such as geofencing.

To use the Google’s Location Services, your app needs to connect to the GooglePlayServicesClient. To connect to the client, your activity (or fragment, or so) needs to implement GooglePlayServicesClient.ConnectionCallbacks and GooglePlayServicesClient.OnConnectionFailedListener interfaces. Here’s a sample code:

    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 
    }

  • Why is locationClient.getLastLocation() null?

The locationClient.getLastLocation() gets the last known location from the client. However, the Fused Location Provider will only maintain background location if at least one client is connected to it. Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and you call getLastLocation() right away in onConnected(), that might not be enough time for the first location to come in. This will result in location being null.

To solve this issue, you have to wait (indeterminately) till the provider gets the location and then call getLastLocation(), which is impossible to know. Another (better) option is to implement the com.google.android.gms.location.LocationListener interface to receive periodic location updates (and switch it off once you get the first update).

    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!!!
    }

In this code, you’re checking if the client already has the last location (in onConnected). If not, you’re requesting for location updates, and switching off the requests (in onLocationChanged() callback) as soon as you get an update.

Note that the locationClient.requestLocationUpdates(locationRequest, this); has to be inside the onConnected callback, or else you will get an IllegalStateException because you will be trying to request for locations without connected to the Google Play Services Client.

  • User has disabled Location Services

Many times, the user would have location services disabled (to save battery, or privacy reasons). In such a case, the code above will still request for location updates, but onLocationChanged will never get called. You can stop the requests by checking if the user has disabled the location services.

If your app requires them to enable location services, you would want to show a message or a toast. Unfortunately, there is no way of checking if the user has disabled location services in Google’s Location Services API. For this, you will have to resort back to Android’s API.

In your onCreate method:

    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;

And use the locationEnabled flag in your onConnected method like this:

    if (location != null) {
    Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
else if (location == null && locationEnabled) {
    locationClient.requestLocationUpdates(locationRequest, this);
}

thanks to Rahul Jiresal

这篇关于Android:LocationManager与Google Play服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆