行動應用程式其中一項與眾不同的功能就是「位置辨識」。 行動裝置使用者會將裝置隨身攜帶,如果您能在應用程式中加入位置辨識功能,就能為使用者提供更符合需求的體驗。
程式碼範例
GitHub 上的 ApiDemos 存放區包含說明如何在地圖上使用位置資訊的範例:
- MyLocationDemoActivity:使用「我的位置」圖層,包括執行階段權限
- LocationSourceDemoActivity:使用自訂
LocationSource
- CurrentPlaceDetailsOnMap:尋找 Android 裝置目前的位置,並顯示該位置地點 (商家或其他搜尋點) 的詳細資料。查看教學課程,瞭解如何在地圖上顯示目前地點的詳細資料。
使用位置資料
Android 裝置可使用的位置資料包括裝置的目前位置 (綜合使用多種技術產生的精確定位)、移動的路線和方法,以及該裝置的移動範圍是否已越過預先定義的地理界線或地理圍欄。視應用程式的需要而定,您有以下幾種使用位置資料的方式可以選擇:
- 「我的位置」圖層能以簡單的方式在地圖上顯示裝置位置,但不提供資料。
- 對於位置資料的所有程式輔助要求,建議您一律使用 Google Play 服務 Location API。
LocationSource
介面可讓您提供自訂的定位服務供應商。
位置存取權
如果您的應用程式需要存取使用者的位置資訊,您必須在應用程式中新增相關的 Android 位置存取權以要求權限。
Android 提供兩種位置存取權:ACCESS_COARSE_LOCATION
和 ACCESS_FINE_LOCATION
。您選擇的權限會決定 API 傳回的位置準確度。視您需要的準確度而定,您只須要求「一項」Android 位置存取權:
android.permission.ACCESS_COARSE_LOCATION
- 允許 API 使用 Wi-Fi 或行動數據 (或兩者皆有) 判斷裝置的位置。API 傳回的位置準確度大約以城市街區為單位。android.permission.ACCESS_FINE_LOCATION
- 允許 API 透過可用的定位服務供應商 (包括全球定位系統 (GPS)) 以及 Wi-Fi 和行動數據,盡可能精確判斷位置。
將權限新增至應用程式資訊清單
將下列其中「一項」權限新增為 Android 資訊清單中 <manifest>
元素的子項。概略位置存取權:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > ... <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> ... </manifest>
或是精確位置存取權:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > ... <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> ... </manifest>
要求執行階段權限
Android 6.0 (Marshmallow) 推出了處理權限的新模式,可簡化使用者安裝與升級應用程式的程序。如果您的應用程式指定 23 以上的 API 級別,就可以使用新的權限模型。
如果您的應用程式支援新的權限模式,且裝置的作業系統是 Android 6.0 (Marshmallow) 以上版本,使用者在安裝或升級應用程式時就不需要授予任何權限。應用程式必須在執行階段檢查是否有必要權限;如果沒有,則必須要求權限。系統會向使用者顯示要求權限的對話方塊。
為了獲得最佳使用者體驗,請務必在內容中要求權限。 如果應用程式運作時必須取得位置,您就應該在應用程式啟動時要求位置存取權。建議您使用歡迎畫面或精靈,誠摯向使用者說明為什麼要授予權限。
如果應用程式僅有部分功能需要取得權限,則在應用程式執行需要權限的動作時,您就應要求位置存取權。
應用程式必須妥善處理使用者未授予權限的情況。舉例來說,如果特定功能需要權限,應用程式可以停用該項功能。如果應用程式必須取得權限才能運作,則可停用其所有功能,並告知使用者必須授予權限。
下列程式碼範例會在啟用「我的位置」圖層前使用支援資料庫檢查權限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { if (mMap != null) { mMap.setMyLocationEnabled(true); } } else { // Permission to access the location is missing. Show rationale and request permission PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE, Manifest.permission.ACCESS_FINE_LOCATION, true); }
以下範例會從支援資料庫中導入 ActivityCompat.OnRequestPermissionsResultCallback
來處理權限要求的結果:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) { return; } if (PermissionUtils.isPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION)) { // Enable the my location layer if the permission has been granted. enableMyLocation(); } else { // Permission was denied. Display an error message // ... } }
如要進一步瞭解 Android 執行階段權限的程式碼範例和最佳做法,請參閱 Android 權限模型的說明文件。
「我的位置」圖層
您可以使用「我的位置」圖層和「我的位置」按鈕,在地圖上向使用者顯示他們目前的位置。呼叫 mMap.setMyLocationEnabled()
可啟用地圖上的「我的位置」圖層。
以下範例顯示「我的位置」圖層的簡單用法:
public class MyLocationDemoActivity extends FragmentActivity
implements OnMyLocationButtonClickListener,
OnMyLocationClickListener,
OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_location_demo);
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap map) {
mMap = map;
// TODO: Before enabling the My Location layer, you must request
// location permission from the user. This sample does not include
// a request for location permission.
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationButtonClickListener(this);
mMap.setOnMyLocationClickListener(this);
}
@Override
public void onMyLocationClick(@NonNull Location location) {
Toast.makeText(this, "Current location:\n" + location, Toast.LENGTH_LONG).show();
}
@Override
public boolean onMyLocationButtonClick() {
Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
// Return false so that we don't consume the event and the default behavior still occurs
// (the camera animates to the user's current position).
return false;
}
}
啟用「我的位置」圖層時,地圖右上角的「我的位置」會顯示按鈕。使用者按一下該按鈕後,攝影機會以裝置的目前位置 (如為已知) 為地圖中心。如果裝置未移動,地圖上會以小藍點標示位置;如果裝置正在移動,則會顯示為 V 形標記。
以下螢幕截圖顯示地圖右上方的「我的位置」按鈕,以及中央的「我的位置」藍點。
呼叫 UiSettings.setMyLocationButtonEnabled(false)
可隱藏「我的位置」按鈕。
您的應用程式可以回應下列事件:
- 如果使用者按一下 [我的位置] 按鈕,您的應用程式就會收到來自
GoogleMap.OnMyLocationButtonClickListener
的onMyLocationButtonClick()
回呼。 - 如果使用者按下「我的位置」藍點,您的應用程式就會收到來自
GoogleMap.OnMyLocationClickListener
的onMyLocationClick()
回呼。
根據我們的《服務條款》
保護使用者隱私權,
隨時告知他們須知事項
請務必告知使用者您使用資料的方式,且切勿採用可識別個別使用者的方法。您必須取得使用者同意,才能使用他們的位置資訊,且必須讓他們可隨時撤銷同意。

Google Play 服務 Location API
如要在 Android 應用程式中新增位置辨識功能,建議優先考量採用 Google Play 服務 Location API 方法。這個方法包括以下功能:
- 判斷裝置位置。
- 監聽位置變化。
- 確定運輸方式,如果該設備是移動。
- 建立和監控預先定義的地理區域,也就是地理圍欄。
Location API 可以讓您輕鬆打造具備位置辨識功能的節能應用程式。和 Maps SDK for Android 一樣,Location API 也是隨附在 Google Play 服務 SDK 中一起發布。如要進一步瞭解 Location API,請參閱 Android 訓練課程「為應用程式加入位置辨識功能」或「Location API 參考資料」。程式碼範例包含在 Google Play 服務 SDK 中。