要求位置存取權

為保護使用者隱私,使用定位服務的應用程式必須要求位置存取權。

要求位置存取權時,請遵循要求的最佳做法 適用於任何其他執行階段權限。 就位置存取權而言,系統包括與位置相關的多項權限,此為一項重要的差異。您要求哪些權限以及如何要求這些權限,視應用程式使用狀況適用的位置資訊需求而定。

本頁面說明不同類型的地點規定,並指引如何在各種情況下要求位置存取權。

位置資訊存取權限類型

每種權限都具有以下特性:

前景位置資訊

如果您的應用程式包含只會分享或接收位置資訊一次,或只在指定時間內分享位置資訊的功能,則必須取得前景位置資訊存取權才能執行該功能。以下提供幾個範例:

  • 使用者可以利用導航應用程式提供的功能,取得即時路線導航。
  • 使用者可以利用訊息應用程式,分享自己目前的所在位置 與其他使用者保持聯絡

如果應用程式的特定功能會在下列任一情況下存取裝置的目前位置,系統就會判定您的應用程式將使用前景位置資訊:

  • 屬於應用程式的活動會顯示在畫面上。
  • 您的應用程式正在執行前景服務。執行前景服務時,系統會透過顯示常駐通知來吸引使用者的注意。應用程式在背景執行時仍會保留位置存取權,例如使用者按下裝置的「主畫面」按鈕或關閉裝置螢幕時。

    此外,建議您宣告前景服務 類型 location,如以下程式碼片段所示。在 Android 10 (API) 29) 或以上版本,您必須宣告此前景服務類型。

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements would go here. -->
    </service>

應用程式要求 ACCESS_COARSE_LOCATION 權限或 ACCESS_FINE_LOCATION 權限時,您必須宣告應用程式需要使用前景位置資訊,如以下程式碼片段所示:

<manifest ... >
  <!-- Always include this permission -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

背景位置資訊

如果應用程式中的特定功能會持續與其他使用者分享位置或使用 Geofencing API,應用程式就需要背景位置資訊存取權。以下提供幾個範例:

  • 使用者可以利用家庭成員位置資訊分享應用程式提供的功能,與家庭成員持續分享位置資訊。
  • 使用者可以利用 IoT 應用程式的功能設定家用裝置,例如 在使用者出門時關閉,並在 也就是使用者返回首頁

只有應用程式在符合前景位置資訊一節所述以外的情況下存取裝置的目前位置時,系統才會判定應用程式將使用背景位置資訊。背景位置資訊精確度與前景位置資訊精確度相同,具體取決於應用程式宣告的位置存取權。

在 Android 10 (API 級別 29) 以上版本中,您必須在應用程式的資訊清單中宣告 ACCESS_BACKGROUND_LOCATION 權限,才能在執行階段要求背景位置資訊存取權。而在舊版 Android 上,當您的應用程式獲得前景位置資訊存取權時,該應用程式也會自動獲得背景位置資訊存取權。

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

精確度

Android 支援下列級別的定位準確度:

概略
提供裝置位置預估值。如果此位置預估值來自 LocationManagerServiceFusedLocationProvider,則此預估值準確度為約 3 平方公里 (約 1.2 平方英里)。宣告 ACCESS_COARSE_LOCATION 權限 (而非 ACCESS_FINE_LOCATION 權限) 時,應用程式可接收達到此準確度的位置。
精確度
提供盡可能準確的裝置位置預估值。如果位置預估值來自 LocationManagerServiceFusedLocationProvider,則此預估值通常約在 50 公尺 (160 英尺) 內,有時甚至不會超過幾公尺 (10 英尺)。宣告 ACCESS_FINE_LOCATION 權限時,應用程式可接收達到此準確度的位置。

如果使用者授予大概位置存取權,則無論應用程式宣告的位置存取權為何,您的應用程式都只能存取大概位置。

即便使用者僅授予概略位置存取權,您的應用程式仍可正常運作。如果應用程式中的某項功能需要透過 ACCESS_FINE_LOCATION 權限來要求精確位置,您可以要求使用者允許應用程式存取精確位置

在執行階段要求位置存取權

如果應用程式中的功能需要位置資訊存取權,請等到使用者與該功能互動後再提出權限要求。此工作流程符合 在情境中要求執行階段權限的最佳做法,如 指南,說明如何要求應用程式 權限

圖 1 說明如何執行此程序的範例。該應用程式包含需要前景位置資訊存取權的「分享位置」功能。應用程式 但不會要求位置存取權,除非使用者選取 「分享位置資訊」按鈕。

使用者選取「分享位置」按鈕後,系統會顯示位置存取權對話方塊
圖 1 需要前景位置資訊存取權的位置資訊分享功能。如果使用者選取「僅在使用該應用程式時允許」,系統就會啟用這項功能。

使用者只授予大概位置資訊

在 Android 12 (API 級別 31) 以上版本中,使用者可以要求擷取您的應用程式 只會取得大概位置資訊 (即使應用程式要求存取 ACCESS_FINE_LOCATION 執行階段權限。

如要處理此潛在的使用者行為,請勿要求 ACCESS_FINE_LOCATION 授予這項權限而是在單一執行階段要求中,要求 ACCESS_FINE_LOCATION 權限和 ACCESS_COARSE_LOCATION 權限。如果只嘗試 ACCESS_FINE_LOCATION,系統會忽略部分版本的要求 Android 12.如果應用程式指定 Android 12 或 升級時,系統會將以下錯誤訊息記錄在 Logcat

ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.

如果您的應用程式同時要求 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION,系統權限對話方塊會包含下列選項:

  • 精確:允許應用程式取得精確位置資訊。
  • 概略:允許應用程式只取得大概位置資訊。

圖 3 顯示對話方塊中包含兩個可協助使用者做出選擇的視覺提示選項。使用者決定 則輕觸三個按鈕中的其中一個,以選取時間長度 授予的權限。

在 Android 12 以上版本中,使用者可以前往系統設定。 即可設定任何應用程式的偏好位置精確度 (無論該應用程式為 目標 SDK 版本即使您的應用程式已安裝在裝置上也是如此 搭載 Android 11 以下版本,則使用者升級到 搭載 Android 12 以上版本。

對話方塊僅顯示概略位置,且包含上下排列的 3 個按鈕
圖 2. 只有在應用程式要求 ACCESS_COARSE_LOCATION 時,才會顯示系統權限對話方塊。
對話方塊有 2 組上下排的選項
圖 3. 應用程式在單一執行階段要求中同時要求 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION 時,即會顯示系統權限對話方塊。

使用者的選擇會影響權限授予

下表根據使用者在權限執行階段對話方塊中選擇的選項,顯示系統授予應用程式的權限:

精確度 概略
使用應用程式時 ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
僅允許這一次 ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
拒絕 沒有位置存取權 沒有位置存取權

如要判斷系統授予應用程式哪些權限,請查看權限要求傳回值。您可以在類似於下列的程式碼中使用 Jetpack 程式庫,也可以使用平台程式庫自行管理權限要求程式碼

Kotlin

val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Precise location access granted.
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Only approximate location access granted.
            } else -> {
                // No location access granted.
            }
        }
    }

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

Java

ActivityResultLauncher<String[]> locationPermissionRequest =
    registerForActivityResult(new ActivityResultContracts
        .RequestMultiplePermissions(), result -> {
            Boolean fineLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_FINE_LOCATION, false);
            Boolean coarseLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_COARSE_LOCATION,false);
            if (fineLocationGranted != null && fineLocationGranted) {
                // Precise location access granted.
            } else if (coarseLocationGranted != null && coarseLocationGranted) {
                // Only approximate location access granted.
            } else {
                // No location access granted.
            }
        }
    );

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(new String[] {
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION
});

要求提升為精確位置

您可以要求使用者將應用程式的存取權從概略位置升級為精確位置。要求使用者升級應用程式的存取權前 但應考量應用程式的用途 需要達到這個精確度如果您的應用程式需要將裝置與附近配對 如果裝置是透過藍牙或 Wi-Fi 連線,建議你使用隨附裝置 配對藍牙 權限,而不是 要求 ACCESS_FINE_LOCATION 權限。

如要要求使用者將應用程式位置存取權從概略位置升級至精確位置,請按照下列步驟執行:

  1. 如有需要,請說明應用程式需要該權限的原因
  2. 再次要求 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION 權限。因為使用者已經允許系統授予 但這次的系統對話方塊和應用程式的大概位置不同, 如圖 4圖 5
對話方塊包含「變更為精確位置」、「僅限這一次」和「拒絕」選項。
圖 4. 使用者先前選取的使用者概略使用應用程式時 (在圖 3 所示對話方塊中)。
對話方塊包含「僅允許這一次」和「拒絕」選項。
圖 5. 先前擁有的使用者 已選取概略僅允許這一次 (在以下對話方塊中的對話方塊: 圖 3)。

最初只請求前景位置資訊

即使應用程式中的多項功能需要位置存取權,其中可能只有部分功能需要背景位置資訊存取權。因此,建議應用程式執行位置存取權漸進式要求,先要求取得前景位置資訊存取權,然後取得背景位置資訊存取權。藉由執行漸進式要求,使用者能進一步瞭解需要背景位置資訊存取權的功能,因此握有更多掌控權和資訊透明度。

圖 6 顯示了專為處理漸進式要求設計的應用程式範例。「顯示目前位置」和「建議臨近位置」功能都需要前景位置資訊存取權。不過,只有「建議附近位置」功能需要背景位置資訊存取權。

啟用前景位置資訊存取權的按鈕與啟用背景位置資訊存取權的按鈕相距半個螢幕長度
圖 6. 兩項功能均須位置存取權,但只有「建議鄰近功能」功能需要背景位置資訊存取權。

執行漸進式要求的程序如下:

  1. 首先,您的應用程式應引導使用者存取需要的功能 前景位置資訊存取權,例如「分享位置資訊」圖 1 中的特徵 或「顯示目前位置」功能,如圖 2 所示。

    在應用程式擁有前景位置資訊存取權之前,建議您禁止使用者存取需要背景位置資訊存取權的功能。

  2. 若使用者日後探索需要背景位置資訊存取權的功能,您可以要求背景位置資訊存取權。

視情況請求背景位置資訊

圖 7. 設定頁面包含一律允許選項,可授予背景位置資訊存取權。

權限對話方塊的內容取決於目標 SDK 版本

應用程式中的功能在執行的裝置中要求背景位置資訊時 Android 10 (API 級別 29),系統權限對話方塊含有一個選項 名稱為 Allow all the time。如果使用者選取此選項,應用程式功能就會取得背景位置資訊存取權。

不過,在 Android 11 (API 級別 30) 及以上版本中,系統對話方塊不包含一律允許選項。使用者必須改為在設定頁面啟用背景位置資訊,如圖 7 所示。

使用者要求背景位置資訊存取權時,您可以遵循最佳做法,協助他們前往設定頁面。授予權限的程序視應用程式的目標 SDK 版本而定。

應用程式指定 Android 11 或以上版本

如果您的應用程式尚未取得 ACCESS_BACKGROUND_LOCATION 權限,且 shouldShowRequestPermissionRationale() 會傳回 true,並向使用者顯示含有以下內容的教育性質 UI:

  • 清楚說明應用程式功能需要存取背景位置資訊的原因。
  • 使用者可以看到的授權背景位置資訊設定選項的標籤 (例如圖 7 中的「一律允許」)。您可以呼叫 getBackgroundPermissionOptionLabel() 以取得此標籤。此方法的傳回值會根據使用者裝置的語言偏好設定進行本地化。
  • 使用者拒絕權限的選項。如果使用者拒絕背景位置資訊存取權,他們應能繼續使用應用程式。
使用者可以輕觸系統通知,來變更應用程式的位置資訊設定
圖 8. 提醒使用者他們已取得應用程式背景位置資訊存取權的通知。

應用程式指定 Android 10 或以下版本

當應用程式功能要求背景位置資訊存取權時,使用者會看到系統對話方塊。此對話方塊包含前往設定頁面上的位置資訊存取權選項。

如果應用程式已經遵循要求位置存取權的最佳做法,則無須做出任何變更即可支援此行為。

使用者可影響背景位置資訊的精確度

如果使用者要求概略位置,使用者的位置存取權對話方塊也會選擇背景位置資訊。於 換句話說,如果使用者將 ACCESS_BACKGROUND_LOCATION 同時只在前景中授予概略位置資訊存取權, 應用程式在背景存取的僅有概略位置資訊存取權。

授予背景位置資訊權限的提醒

在 Android 10 以上版本中,如果應用程式功能會在以下位置存取裝置位置資訊: 使用者授予背景位置資訊後第一次的背景位置資訊 存取後,系統會排程傳送通知給使用者。此通知會提醒使用者,他們已經允許應用程式隨時存取裝置位置資訊。圖 8 顯示了通知範例。

查看應用程式 SDK 依附元件中的位置規定

查看應用程式是否使用任何依附於位置存取權的 SDK (尤其是 ACCESS_FINE_LOCATION 權限)。請參閱有關瞭解 SDK 依附元件行為的媒體文章。

其他資源

如要進一步瞭解 Android 中的位置存取權,請參閱下列資料:

程式碼研究室

影片

範例