安卓12未显示正确的权限请求屏幕。

4
我的应用程序需要精确的用户位置,因为它需要用户在特定位置执行任务。我已经遵循了文档来正确地请求同时具有ACCESS_FINE_LOCATIONACCESS_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

图3:当您的应用程序在单个运行时请求ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION权限时出现的系统权限对话框。
相反,我从文档中看到了图2中的提示。

Figure 2

图2。当您的应用程序仅请求“ACCESS_COARSE_LOCATION”权限时出现的系统权限对话框。
此外,我期望当我已经拥有“COARSE”权限并再次请求“FINE”和“COARSE”权限时,我应该看到“升级到精确定位权限”对话框,但是我根本没有看到提示。
我已在Pixel 3a(物理设备和模拟器)上进行了测试,还收到了其他用户在运行Android 12的各种Pixel和三星Galaxy设备上的报告。
当我们在build.gradle中使用compileSdk 30和targetSdkVersion 30时,问题不存在,但我们需要能够支持新功能和新版本的Android(并且能够升级到仅支持使用较新SDK版本构建的依赖项)。
为什么权限对话框没有正确显示?

你没有明确说明,但基本上问题出现在您将targetSdkVersion升级到31之后是吗? - Pawel
@Pawel,那是正确的。 - Moshe Katz
@MosheKatz 假设这两个权限都在您的实际清单文件中声明,对吧? - PerracoLabs
@PerracoLabs 是的,它们是兼容的。如果不兼容,该应用程序也无法在旧版Android上运行。 - Moshe Katz
1个回答

10
与我在 AndroidManifest.xml 文件中的内容相比,使用 Android Studio 中的“分析 APK”功能生成的 APK 文件中发现了以下条目:
<uses-permission
    android:name="android.permission.ACCESS_FINE_LOCATION"
    android:maxSdkVersion="30" />

很明显,maxSdkVersion 阻止了操作系统给我所需的权限。

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

原来,这个库的开发人员原本使用ACCESS_FINE_LOCATION来连接附近的蓝牙设备,由于Android 12为此提供了单独的权限,他们不再需要它,因此添加了最大SDK版本。
我在ACCESS_FINE_LOCATION <uses-permission />元素中添加了tools:remove="android:maxSdkVersion"属性,现在我的权限正常工作。

1
谢谢,对我有用,我也花了太多天在这上面。 - Ecclesiaste Panda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接