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.LocationListener
và 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.
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 LocationManager
từ hệ thống, thực hiện LocationListener
và gọi requestLocationUpdates
trê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!
- 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.ConnectionCallbacks
và GooglePlayServicesClient.OnConnectionFailedListener
giao 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 location
việ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.LocationListener
giao 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 onConnected
gọi lại, nếu không bạn sẽ nhận được IllegalStateException
vì 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 onLocationChanged
sẽ 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 onCreate
phươ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 locationEnabled
cờ trong onConnected
phươ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.