gpt4 book ai didi

安卓 : LocationManager vs Google Play Services

转载 作者:IT老高 更新时间:2023-10-28 12:58:17 26 4
gpt4 key购买 nike

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

在网上搜索开始的地方时,我发现了一些使用 LocationManager 的教程。类和其他一些使用 Google Play 服务 为了找到用户的位置。

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

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

最佳答案

Android 上的用户位置

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

  • Android 的位置 API

    Android 的位置 API 使用三个不同的提供程序来获取位置 -
  • LocationManager.GPS_PROVIDER — 该提供商使用卫星确定位置。根据条件,此提供程序可能需要一段时间才能返回位置修复。
  • LocationManager.NETWORK_PROVIDER — 该提供商根据蜂窝塔和 WiFi 接入点的可用性确定位置。通过网络查找检索结果。
  • LocationManager.PASSIVE_PROVIDER — 此提供程序将返回其他提供程序生成的位置。当其他应用程序或服务请求位置更新时,您会被动地接收位置更新,而无需您自己实际请求位置。

  • 它的要点是你得到一个 LocationManager 的对象。从系统,实现 LocationListener ,并调用 requestLocationUpdatesLocationManager .

    这是一个代码 fragment :
        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很好地解释了代码。但他们也提到,在大多数情况下,通过使用 Google Location Services API,您将获得更好的电池性能以及更合适的准确度。反而。现在困惑开始了!
  • Google 的位置服务 API

  • Google 的位置服务 API 是 Google Play 服务 APK ( here’s how to set it up) 的一部分。它们建立在 Android 的 API 之上。这些 API 提供了一个“融合位置提供者”,而不是上面提到的提供者。此提供程序会根据准确性、电池使用情况等自动选择要使用的底层提供程序。速度很快,因为您可以从不断更新的系统范围服务中获取位置信息。您还可以使用更高级的功能,例如地理围栏。

    要使用 Google 的定位服务,您的应用需要连接到 GooglePlayServicesClient .要连接到客户端,您的 Activity (或 fragment 等)需要实现 GooglePlayServicesClient.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListener接口(interface)。
    这是一个示例代码:
        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()从客户端获取最后一个已知位置。但是,如果至少有一个客户端连接到 Fused Location Provider,它只会维护后台位置。一旦第一个客户端连接,它将立即尝试获取位置。如果您的 Activity 是第一个连接的客户端并且您调用 getLastLocation()马上在 onConnected() ,这可能不足以让第一个位置进入。这将导致 location正在 null .

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

    在此代码中,您正在检查客户端是否已经拥有最后一个位置(在 onConnected 中)。如果没有,您正在请求位置更新,并在收到更新后立即关闭请求(在 onLocationChanged() 回调中)。

    请注意 locationClient.requestLocationUpdates(locationRequest, this);必须在 onConnected 内回调,否则你会得到一个 IllegalStateException因为您将尝试在未连接到 Google Play 服务客户端的情况下请求位置。
  • 用户已禁用定位服务

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

    如果您的应用需要它们启用定位服务,您可能需要显示一条消息或 toast 。不幸的是,没有办法检查用户是否在 Google 的位置服务 API 中禁用了位置服务。为此,您将不得不求助于 Android 的 API。

    在您的 onCreate方法:
        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;

    并使用 locationEnabled您的旗帜 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);
    }

    更新

    文档已更新,LocationClient 已删除,api 支持从对话框中一键启用 GPS:
    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.
    }
    }
    }
    });

    友情链接 https://developer.android.com/training/location/change-location-settings#prompt

    新位置客户端:FusedLocationProviderClient
      private FusedLocationProviderClient fusedLocationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    }

    建议通过 https://developer.android.com/training/location在执行任何定位任务之前。

    关于安卓 : LocationManager vs Google Play Services,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33022662/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com