Android 12 没有显示正确的权限请求屏幕
Android 12 not showing correct permissions request screen
我的应用程序需要精确的用户位置,因为它需要用户在特定位置才能执行任务。我已经按照 documentation 找到了同时请求 ACCESS_FINE_LOCATION
和 ACCESS_COARSE_LOCATION
的正确方法。
class LocationChooserFragment : BottomSheetDialogFragment() {
// only relevant parts shown
/**
* A utility class that holds all the code for requesting location updates,
* so that we can re-use it in multiple fragments.
*/
private var locationTracker: LocationTracker? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// all the other initialization for viewbinding
tryToGetLocationUpdates()
}
private fun tryToGetLocationUpdates() {
val request = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true && permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true) {
requestLocationUpdates()
}
}
when {
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED -> {
Timber.i("Already have required permissions")
requestLocationUpdates()
}
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) ||
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION) -> {
Timber.i("Showing permission rationale dialog")
// A wrapper to show a dialog that explains what we need permissions for
alertDialog(
title = getString(R.string.permissions),
msg = getString(R.string.why_we_need_location),
onClick = { yes ->
if (yes) {
request.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))
}
}
)
}
else -> {
Timber.i("Prompting for location permissions")
request.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))
}
}
}
private fun requestLocationUpdates() {
if (locationProvider == null) {
locationProvider = LocationProvider(requireContext())
}
locationProvider?.requestLocationUpdates()
}
}
我遇到的问题是我的用户没有收到允许精确定位的提示。
我希望从文档中看到图 3 中的提示:
Figure 3. System permissions dialog that appears when your app requests both ACCESS_FINE_LOCATION
and ACCESS_COARSE_LOCATION
in a single runtime request.
相反,我从文档中看到了图 2 中的提示:
Figure 2. System permissions dialog that appears when your app requests ACCESS_COARSE_LOCATION
only.
此外,我希望当我已经拥有 COARSE
权限并再次请求 FINE
和 COARSE
权限时,我应该会看到“升级到精确权限”对话框,但是我根本没有看到任何提示。
我已经在 Pixel 3a(物理设备和模拟器)上对此进行了测试,并收到了其他用户在 运行 Android 12.[=28 的各种 Pixel 和 Samsung Galaxy 设备上的报告=]
我们在build.gradle
中使用compileSdk 30
和targetSdkVersion 30
时没有出现问题,但我们需要能够支持Android的新功能和新版本(并且能够升级到仅支持使用更新的 SDK 版本构建的依赖项。
为什么权限对话框显示不正确?
将我的 AndroidManifest.xml
与构建应用程序中生成的文件进行比较(使用 Android Studio 中的“分析 APK”功能),我发现生成的 APK 文件具有以下条目:
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
很明显,maxSdkVersion
阻止了 OS 给我所需的权限。
在 app\build
目录中使用 grep
,我找到了 app\build\intermediates\manifest_merge_blame_file\appnameDebug\manifest-merger-blame-appname-debug-report.txt
,其中包括这些行:
17 <uses-permission
17-->C:\path\to\my\appname\app\src\main\AndroidManifest.xml:12:2-76
18 android:name="android.permission.ACCESS_FINE_LOCATION"
18-->C:\path\to\my\appname\app\src\main\AndroidManifest.xml:12:19-73
19 android:maxSdkVersion="30" />
19-->[com.github.50ButtonsEach:flic2lib-android:1.3.1] C:\Users\moshe\.gradle\caches\transforms-3\dced3886509296f1029e8245af379a07\transformed\jetified-flic2lib-android-1.3.1\AndroidManifest.xml:17:9-35
事实证明 this library 的开发人员最初使用 ACCESS_FINE_LOCATION
连接附近的蓝牙设备,并且由于 Android 12 对此有单独的权限,他们不需要它不再所以他们添加了最大 SDK 版本。
我将 tools:remove="android:maxSdkVersion"
属性 添加到 ACCESS_FINE_LOCATION
<uses-permission />
元素,现在我的权限正常工作。
我的应用程序需要精确的用户位置,因为它需要用户在特定位置才能执行任务。我已经按照 documentation 找到了同时请求 ACCESS_FINE_LOCATION
和 ACCESS_COARSE_LOCATION
的正确方法。
class LocationChooserFragment : BottomSheetDialogFragment() {
// only relevant parts shown
/**
* A utility class that holds all the code for requesting location updates,
* so that we can re-use it in multiple fragments.
*/
private var locationTracker: LocationTracker? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// all the other initialization for viewbinding
tryToGetLocationUpdates()
}
private fun tryToGetLocationUpdates() {
val request = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true && permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true) {
requestLocationUpdates()
}
}
when {
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED -> {
Timber.i("Already have required permissions")
requestLocationUpdates()
}
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) ||
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION) -> {
Timber.i("Showing permission rationale dialog")
// A wrapper to show a dialog that explains what we need permissions for
alertDialog(
title = getString(R.string.permissions),
msg = getString(R.string.why_we_need_location),
onClick = { yes ->
if (yes) {
request.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))
}
}
)
}
else -> {
Timber.i("Prompting for location permissions")
request.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))
}
}
}
private fun requestLocationUpdates() {
if (locationProvider == null) {
locationProvider = LocationProvider(requireContext())
}
locationProvider?.requestLocationUpdates()
}
}
我遇到的问题是我的用户没有收到允许精确定位的提示。
我希望从文档中看到图 3 中的提示:
Figure 3. System permissions dialog that appears when your app requests both
ACCESS_FINE_LOCATION
andACCESS_COARSE_LOCATION
in a single runtime request.
相反,我从文档中看到了图 2 中的提示:
Figure 2. System permissions dialog that appears when your app requests
ACCESS_COARSE_LOCATION
only.
此外,我希望当我已经拥有 COARSE
权限并再次请求 FINE
和 COARSE
权限时,我应该会看到“升级到精确权限”对话框,但是我根本没有看到任何提示。
我已经在 Pixel 3a(物理设备和模拟器)上对此进行了测试,并收到了其他用户在 运行 Android 12.[=28 的各种 Pixel 和 Samsung Galaxy 设备上的报告=]
我们在build.gradle
中使用compileSdk 30
和targetSdkVersion 30
时没有出现问题,但我们需要能够支持Android的新功能和新版本(并且能够升级到仅支持使用更新的 SDK 版本构建的依赖项。
为什么权限对话框显示不正确?
将我的 AndroidManifest.xml
与构建应用程序中生成的文件进行比较(使用 Android Studio 中的“分析 APK”功能),我发现生成的 APK 文件具有以下条目:
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
很明显,maxSdkVersion
阻止了 OS 给我所需的权限。
在 app\build
目录中使用 grep
,我找到了 app\build\intermediates\manifest_merge_blame_file\appnameDebug\manifest-merger-blame-appname-debug-report.txt
,其中包括这些行:
17 <uses-permission
17-->C:\path\to\my\appname\app\src\main\AndroidManifest.xml:12:2-76
18 android:name="android.permission.ACCESS_FINE_LOCATION"
18-->C:\path\to\my\appname\app\src\main\AndroidManifest.xml:12:19-73
19 android:maxSdkVersion="30" />
19-->[com.github.50ButtonsEach:flic2lib-android:1.3.1] C:\Users\moshe\.gradle\caches\transforms-3\dced3886509296f1029e8245af379a07\transformed\jetified-flic2lib-android-1.3.1\AndroidManifest.xml:17:9-35
事实证明 this library 的开发人员最初使用 ACCESS_FINE_LOCATION
连接附近的蓝牙设备,并且由于 Android 12 对此有单独的权限,他们不需要它不再所以他们添加了最大 SDK 版本。
我将 tools:remove="android:maxSdkVersion"
属性 添加到 ACCESS_FINE_LOCATION
<uses-permission />
元素,现在我的权限正常工作。