Android: LocationManager vs Google Play Services


151

Tôi muốn xây dựng một ứng dụng xoay quanh việc lấy vị trí hiện tại của người dùng và sau đó tìm các điểm ưa thích (như quán bar, nhà hàng, v.v.) gần với anh ấy / cô ấy thông qua API Google Địa điểm .

Khi tìm kiếm trên web một địa điểm để bắt đầu, tôi đã tìm thấy một số hướng dẫn sử dụng LocationManagerlớp và một số khác sử dụng Dịch vụ Google Play để tìm vị trí của người dùng.

Thoạt nhìn cả hai đều làm điều tương tự, nhưng vì tôi mới làm điều này nên tôi có một chút bối rối và tôi không biết phương pháp nào phù hợp với nhu cầu của mình nhất. Vì vậy, tôi muốn hỏi bạn:

Sự khác biệt giữa hai phương pháp tìm vị trí này (nếu có) là gì?


1
hàn

Câu trả lời:


319

Vị trí người dùng trên Android

Nhận vị trí của người dùng trên Android đơn giản hơn một chút so với trên iOS. Để bắt đầu nhầm lẫn, có hai cách hoàn toàn khác nhau mà bạn có thể làm điều đó. Đầu tiên là sử dụng API Android từ android.location.LocationListenervà thứ hai là sử dụng API Google Play Services com.google.android.gms.location.LocationListener. Chúng ta hãy đi qua cả hai.

  1. API vị trí của Android

    API vị trí của Android sử dụng ba nhà cung cấp khác nhau để có được vị trí -

    • LocationManager.GPS_PROVIDER- Nhà cung cấp này xác định vị trí bằng vệ tinh. Tùy thuộc vào điều kiện, nhà cung cấp này có thể mất một lúc để trả lại vị trí sửa chữa.
    • LocationManager.NETWORK_PROVIDER- Nhà cung cấp này xác định vị trí dựa trên tính khả dụng của các điểm truy cập WiFi và tháp di động. Kết quả được lấy bằng phương pháp tra cứu mạng.
    • LocationManager.PASSIVE_PROVIDER- Nhà cung cấp này sẽ trả lại các vị trí được tạo bởi các nhà cung cấp khác. Bạn thụ động nhận cập nhật vị trí khi các ứng dụng hoặc dịch vụ khác yêu cầu chúng mà không thực sự yêu cầu vị trí đó.

Ý chính của nó là bạn có được một đối tượng LocationManagertừ hệ thống, thực hiện LocationListenervà gọi requestLocationUpdatestrên LocationManager.

Đây là một đoạn mã:

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

Hướng dẫn API của Google về Chiến lược vị trígiải thích mã khá độc đáo. Nhưng họ cũng đề cập rằng trong hầu hết các trường hợp, bạn sẽ có hiệu suất pin tốt hơn, cũng như độ chính xác phù hợp hơn, bằng cách sử dụng API Dịch vụ vị trí của Google thay thế. Bây giờ sự nhầm lẫn bắt đầu!

  1. API dịch vụ vị trí của Google

API dịch vụ vị trí của Google là một phần của APK Dịch vụ Google Play ( đây là cách thiết lập ). Chúng được xây dựng dựa trên API của Android. Các API này cung cấp một Nhà cung cấp vị trí được hợp nhất của Việt Nam Thay vì các nhà cung cấp được đề cập ở trên. Nhà cung cấp này tự động chọn nhà cung cấp cơ bản nào sẽ sử dụng, dựa trên độ chính xác, mức sử dụng pin, v.v ... Thật nhanh chóng vì bạn có được vị trí từ một dịch vụ toàn hệ thống luôn cập nhật nó. Và bạn có thể sử dụng các tính năng nâng cao hơn như định vị địa lý.

Để sử dụng Dịch vụ vị trí của Google, ứng dụng của bạn cần kết nối với GooglePlayServicesClient. Để kết nối với máy khách, hoạt động của bạn (hoặc đoạn hoặc hơn) cần phải thực hiện GooglePlayServicesClient.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListenergiao diện. Đây là một mã mẫu:

    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 
    }
  • Tại sao là locationClient.getLastLocation()null?

Các locationClient.getLastLocation()vị trí được biết đến cuối cùng từ khách hàng. Tuy nhiên, Nhà cung cấp vị trí hợp nhất sẽ chỉ duy trì vị trí nền nếu có ít nhất một khách hàng được kết nối với nó. Khi khách hàng đầu tiên kết nối, nó sẽ ngay lập tức cố gắng để có được một vị trí. Nếu hoạt động của bạn là khách hàng đầu tiên kết nối và bạn gọi getLastLocation()ngay onConnected(), đó có thể không đủ thời gian cho địa điểm đầu tiên đến. Điều này sẽ dẫn đến locationviệc null.

Để giải quyết vấn đề này, bạn phải đợi (không xác định) cho đến khi nhà cung cấp nhận được vị trí và sau đó gọi getLastLocation(), điều này là không thể biết. Một tùy chọn khác (tốt hơn) là triển khai com.google.android.gms.location.LocationListenergiao diện để nhận các bản cập nhật vị trí định kỳ (và tắt nó đi sau khi bạn nhận được bản cập nhật đầu tiên).

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

Trong mã này, bạn đang kiểm tra xem máy khách đã có vị trí cuối cùng chưa (in onConnected) chưa. Nếu không, bạn đang yêu cầu cập nhật vị trí và tắt các yêu cầu (trong onLocationChanged()cuộc gọi lại) ngay khi bạn nhận được bản cập nhật.

Lưu ý rằng locationClient.requestLocationUpdates(locationRequest, this);phải ở trong cuộc onConnectedgọi lại, nếu không bạn sẽ nhận được IllegalStateExceptionvì bạn sẽ cố gắng yêu cầu các vị trí mà không được kết nối với Máy khách Dịch vụ Google Play.

  • Người dùng đã tắt Dịch vụ định vị

Nhiều lần, người dùng sẽ bị vô hiệu hóa dịch vụ định vị (để tiết kiệm pin hoặc lý do riêng tư). Trong trường hợp như vậy, mã ở trên vẫn sẽ yêu cầu cập nhật vị trí, nhưng onLocationChangedsẽ không bao giờ được gọi. Bạn có thể dừng các yêu cầu bằng cách kiểm tra xem người dùng đã tắt dịch vụ định vị chưa.

Nếu ứng dụng của bạn yêu cầu họ kích hoạt dịch vụ định vị, bạn sẽ muốn hiển thị tin nhắn hoặc bánh mì nướng. Thật không may, không có cách nào để kiểm tra xem người dùng có vô hiệu hóa dịch vụ định vị trong API Dịch vụ vị trí của Google hay không. Đối với điều này, bạn sẽ phải dùng đến API của Android.

Trong onCreatephương pháp của bạn :

    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;

Và sử dụng locationEnabledcờ trong onConnectedphương thức của bạn như thế này:

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

CẬP NHẬT

Tài liệu được cập nhật, LocationClient bị xóa và api hỗ trợ bật GPS bằng một cú nhấp chuột từ hộp thoại:

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

Liên kết https://developer.android.com/training/location/change-location-sinstall#prompt

Ứng dụng vị trí mới: FuseLocationProviderClient

  private FusedLocationProviderClient fusedLocationClient;

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

Bạn nên truy cập https://developer.android.com/training/location trước khi thực hiện bất kỳ nhiệm vụ vị trí nào.


9
Bạn có thể sử dụng SettingsApi.checkLocationSettings()để kiểm tra xem người dùng đã kích hoạt Dịch vụ vị trí hay chưa (xem tại đây: developers.google.com/android/reference/com/google/android/gms/ tựa ).
kaolick

3
LocationClient không tồn tại nữa. Để có hướng dẫn cập nhật và rõ ràng về Địa điểm, vui lòng kiểm tra bài viết này: blog.teamtreehouse.com/beginners-guide-location-android
lm2a

1
Và trang đào tạo với ví dụ SettingsApi: developer.android.com/training/location/,
androidguy

2
Bạn cũng có thể tạo một hàng rào địa lý bằng cách sử dụng LocationManager! Api vị trí hợp nhất có hoạt động trên các thiết bị không có dịch vụ google play không?
Muhammad Babar

Đây có thể là một cách khác tốt hơn để kiểm tra trạng thái bật / tắt GPS fun isLocationEnabled(context: Context): Boolean { val locationMode: Int try { locationMode = Settings.Secure.getInt( context.contentResolver, Settings.Secure.LOCATION_MODE ) } catch (e: SettingNotFoundException) { e.printStackTrace() return false } return locationMode != Settings.Secure.LOCATION_MODE_OFF }
Wahib Ul Haq

32

Theo kinh nghiệm của tôi, "độ chính xác phù hợp hơn" không có nghĩa là tốt hơn bằng mọi cách. Trừ khi tôi thiếu thứ gì đó, nếu bạn muốn chắc chắn rằng GPS được sử dụng, LocationManager là cách duy nhất để đi. Chúng tôi theo dõi các phương tiện bằng ứng dụng của mình và, một lần nữa, trừ khi tôi thiếu thứ gì đó, Google Play Services cung cấp một số vị trí rất không chính xác khá thường xuyên.


2
Có, từ kinh nghiệm của tôi, Google Play Services đôi khi cung cấp vị trí không chính xác.
VY

2
Có, API Dịch vụ vị trí của Google Play Services có thể cung cấp thông tin Vị trí rất sai lệch. Modem WiFi được di chuyển, modem WiFi được cập nhật với thông tin vị trí không chính xác (nghĩa là nếu vị trí bị giả mạo bởi thiết bị Android cập nhật vị trí của modem WiFi) và có một số trường hợp khác có thể dẫn đến dữ liệu Vị trí không chính xác từ tam giác modem WiFi. Trong tất cả các ứng dụng của chúng tôi, nơi Vị trí chính xác là bắt buộc, chúng tôi chỉ sử dụng GPS.
user1608385

27

Bạn nên sử dụng api vị trí Dịch vụ Google Play thay vì LocationManager. Theo các tài liệu:

API vị trí dịch vụ Google Play được ưa thích hơn API vị trí khung Android (android.location) như một cách để thêm nhận thức về vị trí cho ứng dụng của bạn. Nếu bạn hiện đang sử dụng API vị trí khung Android, bạn nên chuyển sang API vị trí dịch vụ Google Play càng sớm càng tốt.

Về lý do để chuyển đổi, Google nói điều này:

API dịch vụ vị trí của Google, một phần của Dịch vụ Google Play, cung cấp khung công tác cấp cao, mạnh mẽ hơn, tự động xử lý các nhà cung cấp vị trí, chuyển động của người dùng và độ chính xác của vị trí. Nó cũng xử lý lập lịch cập nhật vị trí dựa trên các thông số tiêu thụ điện năng bạn cung cấp. Trong hầu hết các trường hợp, bạn sẽ có hiệu suất pin tốt hơn, cũng như độ chính xác phù hợp hơn, bằng cách sử dụng API Dịch vụ vị trí.


2
Bạn có liên kết đến tài liệu mà các trích dẫn này là từ? Sẽ rất thú vị để xem liệu Google có nói điều gì khác bây giờ không.
Edward Brey

3
Tất nhiên họ nói điều này, vì họ muốn dữ liệu vị trí của bạn!
Flyview

Khi bạn thêm dịch vụ Google play vào ứng dụng của mình, nếu người dùng cài đặt ứng dụng của bạn, anh ta sẽ được nhắc "cập nhật" dịch vụ google play để sử dụng ứng dụng của bạn. Trong trường hợp điện thoại của anh ấy / cô ấy gần đầy (với memes và nội dung whatsapp) hoặc người dùng không có dữ liệu, xin lỗi bạn, bạn của tôi
Tiến sĩ Deo

2
@Flyview Yep! Lol, cách họ nói nó làm cho nó có vẻ như là một giải pháp kỳ diệu! Hạn chế lớn nhất là bạn cần Dịch vụ Google Play trên thiết bị !!!
varun

25

Tôi đã sử dụng API Dịch vụ vị trí của Google khá lâu. Nó có lợi thế, vì nó gói gọn sự phức tạp của việc có một số nguồn để xác định vị trí. Tuy nhiên, nó gói gọn quá nhiều , để khi bạn có được một vị trí lạ, bạn không có cách nào để xác định vị trí lạ đó đến từ đâu.

Trong cuộc sống thực, tôi đã có một vài giá trị kỳ dị xuất hiện, cách vị trí thực tế 10 km. Giải thích duy nhất là những vị trí điên rồ này xuất phát từ lỗi trong cơ sở dữ liệu Wi-Fi hoặc NWK của Google - những lỗi sẽ luôn tồn tại, do các cấu trúc liên kết mạng và Wi-Fi thay đổi mỗi ngày. Nhưng thật không may (và đáng ngạc nhiên) API cung cấp cho bạn không có thông tin nào về cách một vị trí riêng lẻ được tạo ra.

nhập mô tả hình ảnh ở đây

Điều này khiến bạn gặp phải các vấn đề về việc phải lọc ra các giá trị kỳ dị dựa trên việc kiểm tra tính hợp lý về tốc độ, gia tốc, khả năng chịu lực, v.v.

... hoặc quay lại API khung cũ tốt và chỉ sử dụng GPS, đó là điều tôi quyết định làm cho đến khi Google cải thiện API hợp nhất.


7

API dịch vụ vị trí của Google, một phần của Dịch vụ Google Play, cung cấp khung công tác cấp cao, mạnh mẽ hơn, tự động xử lý các nhà cung cấp vị trí , chuyển động của người dùng độ chính xác của vị trí . Nó cũng xử lý lập lịch cập nhật vị trí dựa trên các thông số tiêu thụ điện năng bạn cung cấp. Trong hầu hết các trường hợp, bạn sẽ có hiệu suất pin tốt hơn , cũng như độ chính xác phù hợp hơn, bằng cách sử dụng API Dịch vụ vị trí.

Sự khác biệt chi tiết hơn giữa hai API vị trí dịch vụ Google PlayAPI vị trí khung Android có thể được tìm thấy ở đây


Tôi đã sử dụng câu trả lời của bạn để trả lời câu hỏi của riêng tôi nếu điều đó ổn. Cảm ơn rất nhiều! stackoverflow.com/questions/39852955/ từ
Leniaal

@Leniaal vì vậy bạn không nghĩ rằng câu trả lời của tôi xứng đáng được nâng cấp?
Dhruvam Gupta

Đó là một tài liệu cũ 3 năm. Nhưng đây là một cộng 1
vẽ

5

Có, API Dịch vụ vị trí của Google Play Services có thể cung cấp thông tin Vị trí rất sai lệch. Modem WiFi được di chuyển, modem WiFi được cập nhật với thông tin vị trí không chính xác (nghĩa là nếu vị trí bị giả mạo bởi thiết bị Android cập nhật vị trí của modem WiFi) và có một số trường hợp khác có thể dẫn đến dữ liệu Vị trí không chính xác từ tam giác modem WiFi. Trong tất cả các ứng dụng của chúng tôi, nơi Vị trí chính xác là bắt buộc, chúng tôi chỉ sử dụng GPS.


4

Sự khác biệt giữa hai API vị trí dịch vụ Google Play và API vị trí khung Android dựa trên dịch vụ GPS

Hợp nhấtLocationProviderClient

  1. Đối với lần tìm nạp đầu tiên, vị trí không được rỗng (nghĩa là: Một số ứng dụng khác cần cập nhật vị trí Last Unknown trong cơ sở dữ liệu GoogleplayService. Nếu nó là null, cần phải làm việc xung quanh)
  2. Đối với Tìm nạp tuần tự tiếp theo, nó sử dụng requestLocationUpdates()phương thức để tìm nạp vị trí.
  3. Việc tìm nạp vị trí chỉ dựa trên locationRequest.setInterval(milliseconds)setFastestInterval(milliseconds), không dựa trên thay đổi vị trí của người dùng
  4. Giá trị LatLng được trả về chỉ chứa 7 giá trị thập phân (ví dụ: 11.9557996, 79.8234599), không chính xác
  5. Được khuyến nghị, khi yêu cầu ứng dụng của bạn mất khoảng cách vị trí hiện tại không đáng kể (độ chính xác 50 - 100 mét)
  6. Sử dụng pin hiệu quả.

Vị trí quản lý Api

  1. Tìm nạp vị trí người dùng được gọi bằng locationManager.requestLocationUpdates ()
  2. Tìm nạp vị trí dựa trên thay đổi vị trí của người dùng và khoảng thời gian locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)

  3. Giá trị LatLng được trả về có chứa 14 giá trị thập phân (ví dụ: 11.94564594963342 79.81166719458997) giá trị vị trí chính xác

  4. Đề xuất cho ứng dụng dựa trên vị trí, khi cần chính xác hơn ngay cả trong mét.
  5. Việc sử dụng pin dựa trên khoảng thời gian tìm nạp và khoảng cách tìm nạp.

Chào! 1 ° nhiều nhất là 111_111 mét (20_000_000 / 180). Vậy, 0,0000001 ° là 0,011m = 1 cm. Tôi không biết bạn cần độ phân giải GPS tốt hơn ở đâu. Và tôi thậm chí không biết, làm thế nào bạn có thể đạt được độ phân giải GPS tốt hơn.
babay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.