作者:Joe Birch
翻譯:Google Translate + Leelion6
所需材料及原始碼下載:github.com/hitherejoe/…
釋出日期:2019年3月18日
上個月我們看到了Android Q beta版本的宣佈 ? 隨之帶來了一系列令人興奮的變化,我們需要了解這些變化才能讓我們的應用程式做好準備。
正如 Android Q 的 測試版發行說明中所述,新版變化之一是應用內處理使用者獲取位置的方式——這些更改會影響前臺和後臺中對位置的訪問,使得我們的使用者可以更好地按照他們的想法來選擇應用何時能夠訪問其位置,以及使用者僅在使用應用的時候做一些限制。在這篇文章中,我想讓你快速瞭解這些變化將如何影響應用程式,以及我們需要做些什麼來適應這些變化。
前臺獲取位置許可權
在某些情況下,您的應用程式需要在前臺執行時訪問使用者位置。例如,您的應用可能會向使用者提供導航功能,一旦使用者開啟了應用的導航首頁,您就會希望繼續訪問其位置以繼續向他們提供導航服務。如果您的應用程式需要訪問此時的位置資料,那麼讓您的使用者知道訪問的原因就非常重要。
首先,使用使用者位置的任何此類服務都需要宣告為位置前臺服務。這可以通過在 manifest
清單檔案中宣告服務時使用 foregroundServiceType 來達成。
<service
android:name="ForegroundService"
android:foregroundServiceType="location"/>
複製程式碼
在嘗試啟動前臺服務之前,我們需要確保已獲得使用者所需的許可權,我們可以通過檢查 ACCESS_COARSE_LOCATION 來確認這一點。對現在來說,這不是一個新的許可權——實際上,它從API級別1開始就存在了。然而,我們以前只需要在應用程式 manifest
清單檔案中定義, 現在我們必須在執行時請求此許可權。您可以看到,現在我們的使用者對如何使用該許可權有了更多的控制。
val hasLocationPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasLocationPermission) {
// handle location update
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), REQUEST_CODE_FOREGROUND)
}
複製程式碼
在上面的程式碼中,您可以看到我們首先檢查是否具有位置許可權。如果是這樣,我們可以繼續處理位置流程,否則必須請求使用者的許可。如果是這種情況,那麼我們將在呼叫類中的 onRequestPermissionsResult()
的回撥中接收許可權狀態。
當我們請求此許可權時,我們的使用者將顯示以下對話方塊:
正如您所看到的,請求許可權的意圖已經非常明確 - 應用程式只能在前臺訪問其位置(例如,正在使用該應用程式)。如果使用者在任何時候拒絕了此許可權,並且應用再次請求獲取許可權時,那麼對話方塊的內容將產生略微變化:
與Android中的獲取執行時許可權的工作方式類似,使用者可以選擇不再被詢問一個許可權請求。因為有這個功能的存在,所以開發者只能在需要的時候採取請求這個前臺位置訪問許可權,這一點很重要,會讓使用者可以更明確地知道何時需要許可權,而不是讓使用者覺得應用在無緣無故地請求許可權。
後臺獲取位置許可權
當我們的應用程式在後臺訪問使用者位置時,實現的方式會有不同。首先需要為我們的 manifest
清單檔案新增一個新許可權 —— ACCESS_BACKGROUND_LOCATION 。雖然這是在 manifest
清單中宣告的,但使用者仍可隨時撤銷它。
<manifest>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>
複製程式碼
請注意,這裡我們不需要將 foregroundServiceType 服務型別新增到我們的服務宣告中,這是因為我們不需要那種短暫的許可權就可以在應用外執行? 這個背景許可權已經使我們的應用程式能夠執行此操作。
譯者注:此處未能理解作者的原意,所以不知如何翻譯,期望有明白的大佬可以在評論區告知
作者原句:this is because we don’t need momentary permission to run outside of our app – this background permission already gives our application the ability to do this.
除了上述內容之外,使用者還需要在執行時授予許可權。因此,在我們嘗試從後臺訪問使用者位置之前,我們需要確保我們擁有使用者所需的許可權。我們可以通過檢查 ACCESS_BACKGROUND_LOCATION 許可權來完成此操作。您可以再次看到它現在如何讓我們的使用者更好地控制如何使用此許可權,並避免濫用後臺位置訪問。
我們檢查許可權的程式碼如下所示:
val hasForegroundLocationPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasForegroundLocationPermission) {
val hasBackgroundLocationPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasBackgroundLocationPermission) {
// handle location update
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUEST_CODE_BACKGROUND)
}
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUEST_CODE_BACKGROUND)
}
複製程式碼
您會注意到此程式碼與我們為前臺位置許可權定義的檢查非常相似。在這裡,我們檢查兩種許可權,如果使用者由於某種原因拒絕我們進行後臺訪問,我們會在位置檢索中給予回退。
當我們請求此許可權時,我們的使用者將顯示以下對話方塊:
許可的意圖已經非常明確 - 我們的應用程式將能夠在後臺訪問他們的位置。如果使用者在任何時候拒絕了此許可權並且我們再次請求它,那麼對話方塊顯示的內容將會略微變化:
與Android中的獲取執行時許可權的工作方式類似,使用者可以選擇不再被詢問一個許可權請求。因為有這個功能的存在,所以開發者只能在需要的時候採取請求這個後臺位置訪問許可權,指導使用者可以更明確地知道何時需要許可權,而不是讓使用者覺得應用在無緣無故地請求許可權。
總結
我們可以從這篇文章中看到,Android Q改變了應用程式獲取位置許可權的方式。我們的應用程式將無法再從服務中自由訪問使用者位置,無論是在前臺還是後臺。
為了應用具有更好的相容性,如果您的應用程式未以Q為目標,則在宣告 COARSE 或 FINE 許可權時將新增 ACCESS_BACKGROUND_LOCATION 許可權。同樣,在執行時請求兩者中的任何一個也將授予許可權。
這些更改使我們的使用者可以更好地控制應用程式訪問其位置的方式,從而使我們能夠建立具有注重使用者隱私和安全性的應用程式。有關這些位置變化的任何問題?歡迎在評論中與我們聯絡!