Get your current location / 取得GPS位置
取得GPS位置
因為要取得目前位置是 Google Play services APIs ,為了使用它,需要先準備好使用環境。
1. 先打開 Gradle 的 build.gradle (Module: app) ,添加他的相依函式庫 :
dependencies { implementation "com.google.android.gms:play-services-location:$googlePlayServiceVersion" ... }
2. 因此需要確認使用者是有提供 Google Play Service 的
GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this)
3. 接著需要向使用者要求權限
在 AndroidManifest.xml 加上要求位址的權限,這邊 google 提供兩種權限:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
4. 然後要在需要用到經緯度的功能,都需要先檢查是否有權限:
Android sdk 23 (M 棉花糖) 以後變成要求使用者權限,不再能在安裝 APK 時,就直接取得,所以這邊會先檢查使用者的運行版本。
Build.VERSION.SDK_INT < Build.VERSION_CODES.M
接著在 Activity 內呼叫該函式,來檢查該有的權限是否已授權:
checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED
5. 重新要權限
在版本 ≥ M 的情況下我們需要先呼叫
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)
特別注意:關於這個權限要求,會需要裝置端允許定位為精確度模式。
這邊需要小心的是使用者可能會因為系統的這個詢問選擇不同意而把模式改動鎖死。
鎖死的狀態我還不太清楚為什麼會發生,但是會造成設定怎麼調整都還是拿不到定位
這時候只能重新開機,藉由狀態重置才有辦法恢復為可以用高定位精確度的狀態。
(鎖死狀態下 GoogleMap 也是會發生藍點定位失效!)
6. 拿到設定裡的定位模式:
/** * Location mode: * High Accuracy: Wi-Fi/Network + GPS * Device only: GPS * Save Battery: Wi-Fi/Network * @param context */ private void checkLocationMode(Context context) { LocationManager manager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); boolean isGpsEnabled = manager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean isNetworkEnabled = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); }
7. 在授權視窗後,onRequestPermissionsResult 可以收到來自使用者的選項回應。
@CallSuper override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_LOCATION_PERMISSIONS) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { getLocation() } else getLocationActionFail() } }
8. 正式用 LocationService 取得定位
/** * Get Location with new api client. {@link FusedLocationProviderClient}<br> * @param activity * @param getLocationCallback */ @SuppressWarnings("MissingPermission") public void getLastLocation(Activity activity, final GetLocationCallback getLocationCallback) { LocationServices.getFusedLocationProviderClient(activity).getLastLocation() .addOnCompleteListener(activity, new OnCompleteListener<Location>() { @Override public void onComplete(@NonNull Task<Location> task) { if (task.isSuccessful()) { if(task.getResult() != null) { latestLocation = task.getResult(); getLocationCallback.onGetLocation( latestLocation.getLatitude(), latestLocation.getLongitude()); } else { //show gps mode is not high accuracy in version higher than android M getLocationCallback.onGetLocationNull(); } } else { if(latestLocation != null) getLocationCallback.onLocationIsNotChanged( latestLocation.getLatitude(), latestLocation.getLongitude()); } } }); }
9. 接上自定義的 GetLocationCallback 就可以取的最後的經緯度了。
各位可以在使用上調整成自己需要的回調,像是失敗回調的部分。
10. 如果是需要持續更新位置的功能(比較強調機動性的功能)可以參考使用 FusedLocationProviderClient.requestLocationUpdates
需要注意的部分就是在不使用時要記得釋放掉 Callback!
@Override public void release() { /* remove location update */ if(mFusedLocationClient != null) mFusedLocationClient.removeLocationUpdates(locationCallback); }
留言
張貼留言