ตำแหน่งของผู้ใช้บน Android
การรับตำแหน่งของผู้ใช้บน Android นั้นค่อนข้างตรงไปตรงมาน้อยกว่าบน iOS เพื่อเริ่มต้นความสับสนมีสองวิธีที่แตกต่างกันโดยสิ้นเชิงที่คุณสามารถทำได้ เป็นครั้งแรกที่มีการใช้ API Android จากandroid.location.LocationListener
และที่สองคือการใช้ com.google.android.gms.location.LocationListener
API เรามาดูทั้งคู่กัน
API ตำแหน่งของ Android
API ตำแหน่งของ Android ใช้ผู้ให้บริการสามรายในการรับตำแหน่ง -
LocationManager.GPS_PROVIDER
- ผู้ให้บริการนี้กำหนดสถานที่โดยใช้ดาวเทียม ผู้ให้บริการนี้อาจใช้เวลาสักครู่ในการส่งคืนการแก้ไขตำแหน่งทั้งนี้ขึ้นอยู่กับเงื่อนไข
LocationManager.NETWORK_PROVIDER
- ผู้ให้บริการนี้จะกำหนดสถานที่ตามความพร้อมของ Cell Tower และจุดเชื่อมต่อ WiFi ผลลัพธ์จะถูกค้นคืนโดยการค้นหาเครือข่าย
LocationManager.PASSIVE_PROVIDER
- ผู้ให้บริการนี้จะส่งคืนตำแหน่งที่สร้างโดยผู้ให้บริการรายอื่น คุณจะได้รับการอัปเดตตำแหน่งอย่างอดทนเมื่อแอปพลิเคชันหรือบริการอื่นร้องขอโดยไม่ขอตำแหน่งด้วยตนเอง
สรุปสาระสำคัญของมันคือการที่คุณจะได้รับวัตถุของLocationManager
จากระบบใช้LocationListener
และเรียกบนrequestLocationUpdates
LocationManager
นี่คือข้อมูลโค้ด:
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 เกี่ยวกับกลยุทธ์สถานที่ตั้งอธิบายรหัสได้เป็นอย่างดี แต่พวกเขายังกล่าวว่าในกรณีส่วนใหญ่คุณจะได้รับประสิทธิภาพของแบตเตอรี่ที่ดีขึ้นรวมถึงความแม่นยำที่เหมาะสมยิ่งขึ้นโดยใช้Google Location Services APIแทน ตอนนี้ความสับสนเริ่มขึ้นแล้ว!
- API บริการตำแหน่งของ Google
API บริการตำแหน่งของ Google เป็นส่วนหนึ่งของ APK ของ Google Play Services ( นี่คือวิธีการตั้งค่า ) พวกมันถูกสร้างขึ้นบน API ของ Android API เหล่านี้มี "ผู้ให้บริการตำแหน่งที่หลอมรวม" แทนผู้ให้บริการที่กล่าวถึงข้างต้น ผู้ให้บริการนี้จะเลือกผู้ให้บริการพื้นฐานที่จะใช้โดยอัตโนมัติตามความถูกต้องการใช้งานแบตเตอรี่ ฯลฯ มันรวดเร็วเพราะคุณได้รับตำแหน่งจากบริการทั่วทั้งระบบที่คอยอัปเดตอยู่เสมอ และคุณสามารถใช้คุณสมบัติขั้นสูงเพิ่มเติมเช่นการหาตำแหน่งทางภูมิศาสตร์
การใช้บริการสถานที่ตั้งของ Google app 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()
ได้รับตำแหน่งที่ทราบล่าสุดจากลูกค้า อย่างไรก็ตามผู้ให้บริการตำแหน่งที่หลอมรวมจะรักษาตำแหน่งพื้นหลังเฉพาะเมื่อมีอย่างน้อยหนึ่งไคลเอ็นต์ที่เชื่อมต่ออยู่ เมื่อไคลเอนต์แรกเชื่อมต่อแล้วมันจะพยายามหาที่ตั้งทันที หากกิจกรรมของคุณเป็นลูกค้าคนแรกที่จะเชื่อมต่อและคุณโทร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 Services Client
- ผู้ใช้ปิดใช้งานบริการตำแหน่ง
หลายครั้งที่ผู้ใช้ปิดใช้งานบริการระบุตำแหน่ง (เพื่อประหยัดแบตเตอรี่หรือเหตุผลด้านความเป็นส่วนตัว) ในกรณีดังกล่าวรหัสด้านบนจะยังคงร้องขอการอัปเดตตำแหน่ง แต่onLocationChanged
จะไม่ถูกเรียก คุณสามารถหยุดคำขอได้โดยตรวจสอบว่าผู้ใช้ปิดใช้งานบริการระบุตำแหน่งหรือไม่
หากแอปของคุณต้องการให้เปิดใช้งานบริการระบุตำแหน่งคุณจะต้องแสดงข้อความหรือขนมปังปิ้ง ขออภัยไม่มีวิธีตรวจสอบว่าผู้ใช้ปิดใช้งานบริการระบุตำแหน่งใน API บริการตำแหน่งของ Google หรือไม่ สำหรับสิ่งนี้คุณจะต้องหันกลับไปใช้ API ของ Android
ใน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);
}
UPDATE
อัปเดตเอกสารแล้ว 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ก่อนที่จะทำงานเกี่ยวกับตำแหน่ง