简体   繁体   English

Android 11 运行时权限

[英]Android 11 Runtime Permissions

Before a few days, the code is working fine not having issues with permissions.几天前,代码运行良好,没有权限问题。

I am not able to grant permission at run-time also having issues while granting permissions from the setting.我无法在运行时授予权限,在从设置中授予权限时也遇到问题。 (App permission detail page). (应用程序权限详细信息页面)。

var permissions = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
        arrayOf(Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
    } else {
        arrayOf(Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
    }

Requesting For Permissions on the appropriate button click.单击相应按钮上的请求权限。

permissionResultLauncher =
        registerForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
        ) { permissions ->
            var allPermissionGranted = true
            permissions.entries.forEach {
                if (!it.value) {
                    Log.e(TAG, "Permission ${it.key} granted : ${it.value}")
                    allPermissionGranted = false
                }
            }
            if (!permissionDeniedDialog && !allPermissionGranted) {
                showDialog(
                        "Required",
                        "App needs Bluetooth and Location permissions to scan bluetooth devices.",
                        "Later",
                        "Allow",
                        object : DialogView.ButtonListener {
                            override fun onNegativeButtonClick(dialog: AlertDialog) {
                                dialog.dismiss()
                                val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                                        Uri.fromParts("package", requireActivity().applicationContext.packageName, null))
                                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                                startActivity(intent)
                            }

                            override fun onPositiveButtonClick(dialog: AlertDialog) {
                                dialog.dismiss()
                                requestRequirdPermissions()
                            }
                        })
            } else {
                val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                        Uri.fromParts("package", requireActivity().applicationContext.packageName, null))
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                startActivity(intent)
            }
            permissionDeniedDialog = true
        }
permissionResultLauncher.launch(permissions)

Function for checking permissions权限检查功能

private fun checkPermission(): Boolean {
        for (permission in permissions) {
            if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) return false
        }
        return true
    }

Can someone let me know why the above not working?.有人可以让我知道为什么上述方法不起作用吗? the system was on the result directly and the app was redirecting the app to the setting page, but I am not able to grant permission from the settings page too.系统直接在结果上,应用程序正在将应用程序重定向到设置页面,但我也无法从设置页面授予权限。

Is this OS Specific?, anyone having the same issues with ColorOS 11 ?.这是特定于操作系统的吗?是否有人与 ColorOS 11 有相同的问题?。 Please guide me if anything is missing from my side.如果我身边缺少任何东西,请指导我。

Device: OPPO F17 Pro OS: Color OS 11, Android 11 Based设备:OPPO F17 Pro 操作系统:Color OS 11,基于Android 11

Note:笔记:

Above code, with Samsung device, Android 11 Based (OneUI 3.1), App was not asking for runtime but after redirecting on setting page, I am granting location permission and app was working fine, regarding OPPO i am not able grant permission from setting page.上面的代码,使用三星设备,基于 Android 11(OneUI 3.1),应用程序没有要求运行时,但在设置页面重定向后,我授予位置权限并且应用程序运行良好,关于 OPPO 我无法从设置页面授予权限.

What tried :尝试了什么:

  var permissions = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
    arrayOf(Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
} else {
    arrayOf(Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_COARSE_LOCATION)
}


private fun requestRequirdPermissions() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
            permissionResultLauncher.launch(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION))
        }
        else
        {
            permissionResultLauncher.launch(arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION ))
        }
    }

Try this way may help you试试这个方法可能对你有帮助

fun checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            var permissions: ArrayList<String> = ArrayList<String>()
            permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION)
            val listPermissionsNeeded: ArrayList<String> = ArrayList()
            for (p in permissions) {
                var result = ContextCompat.checkSelfPermission(this, p!!)
                if (result != PackageManager.PERMISSION_GRANTED) {
                    listPermissionsNeeded.add(p)
                }
            }

            if (!listPermissionsNeeded.isEmpty()) {
                ActivityCompat.requestPermissions(
                        this,
                        listPermissionsNeeded.toTypedArray(),
                        CODE
                )
            } else {
                next()
            }
        } else {
            next()
        }
    }

    override fun onRequestPermissionsResult(
            requestc: Int,
            permissions: Array<String>,
            grantRes: IntArray
    ) {
        super.onRequestPermissionsResult(requestc, permissions, grantRes);
        when (requestc) {
            CODE -> {
                var isGrant = true
                if (grantRes.size > 0) {
                    for (i in 0 until grantResults.size) {
                        if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                            isGrant = false
                        }
                    }
                }
                if (isGrant) {
                    next()
                } else {
                    checkRationalePermission(permissions)
                }
            }
        }
    }


    var alertDialogRatinal: android.app.AlertDialog? = null
    fun checkRationale(permissions: Array<String>) {
        if (alertDialogRatinal != null && alertDialogRatinal!!.isShowing || permissions.size == 0) {
            return
        }
        var someDenied = false
        for (permission in permissions) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(
                    this@Activity,
            permission!!
                )
            ) {

            } else {
                if (ActivityCompat.checkSelfPermission(
                        this@Activity,
                permission
                    ) == PackageManager.PERMISSION_GRANTED
                ) {
                } else {
                    someDenied = true
                }
            }
        }
        if (someDenied) {
            val alertDialogBuilder =
                    android.app.AlertDialog.Builder(this@Activity)
            alertDialogRatinal = alertDialogBuilder.setTitle("Permissions Required")
                    .setMessage(
                            "Please open settings, go to permissions and allow them."
                    )
                    .setPositiveButton(
                            "Settings"
                    ) { dialog, which ->
                    val intent = Intent(
                    Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                    Uri.fromParts(
                            "package",
                            this@Activity.getPackageName(),
                null
                        )
                    )
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                startActivityForResult(intent, 100)
            }
                .setNegativeButton(
                    "Cancel"
            ) { dialog, which -> }
                .setCancelable(false)
                    .create()
            alertDialogRatinal!!.show()
        }
    }

My issue was fixed by the system reset, but according to comments and documents please follow the below guidelines for the location permission.我的问题已通过系统重置解决,但根据评论和文档,请遵循以下位置许可指南。

Thanks Pawel for comments,感谢Pawel的评论,

Ref: https://stackoverflow.com/a/66321942/9909365参考: https : //stackoverflow.com/a/66321942/9909365

Background location permission does not work like other permissions.后台位置权限与其他权限不同。 It's a request to elevate location permission from foreground-only to foreground & background.这是将位置权限从仅前景提升到前景和背景的请求。

User has to consciously select "Allow all the time" in order to do that and grant background location permission.用户必须有意识地选择“始终允许”才能这样做并授予后台位置权限。 Otherwise that permission is considered denied.否则,该许可被视为被拒绝。

You cannot even request background location unless foreground location is already granted - when system permission activity shows up it should already have option 2 or 3 selected.除非已经授予前台位置,否则您甚至无法请求后台位置 - 当系统权限活动出现时,它应该已经选择了选项 2 或 3。

See https://developer.android.com/training/location/permissions#request-background-location请参阅https://developer.android.com/training/location/permissions#request-background-location

Note:笔记:

When your app is using this background location please be prepared with a short video that demonstrates the location-based feature in your app that requires access to location in the background (while the app is not in use).当您的应用使用此后台位置时,请准备一段简短的视频,演示您的应用中基于位置的功能,该功能需要在后台访问位置(应用未使用时)。

See https://support.google.com/googleplay/android-developer/answer/9799150请参阅https://support.google.com/googleplay/android-developer/answer/9799150

private val requestIdMultiplePermissions = 1
private val permissionsRequest: ArrayList<String> =
    arrayListOf(READ_CALENDAR
            , CAMERA)
findViewById<Button>(R.id.multiplePermissionBtn).setOnClickListener {
            if (checkMultipleRequestPermissions()) {
                doOperation()
            }
}
 private fun doOperation() {
        Toast.makeText(this, "Successfully granted", Toast.LENGTH_LONG).show()
    }
private fun checkMultipleRequestPermissions(): Boolean {
        val listPermissionsNeeded: MutableList<String> = ArrayList()

        for (p in permissionsRequest) {
            val result = ContextCompat.checkSelfPermission(this, p)
            if (result != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(p)
            }
        }

        if (listPermissionsNeeded.isNotEmpty()) {
            ActivityCompat.requestPermissions(
                this,
                listPermissionsNeeded.toTypedArray(),
                requestIdMultiplePermissions
            )
            return false
        }
        return true
    }
override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == requestIdMultiplePermissions) {
            if (grantResults.isNotEmpty()) {
                var isGrant = true
                for (element in grantResults) {
                    if (element == PackageManager.PERMISSION_DENIED) {
                        isGrant = false
                    }
                }
                if (isGrant) {
                    doOperation()
                } else {
                    var someDenied = false
                    for (permission in permissions) {
                        if (!ActivityCompat.shouldShowRequestPermissionRationale(
                                this,
                                permission
                            )
                        )  {
                            if (ActivityCompat.checkSelfPermission(
                                    this,
                                    permission
                                ) == PackageManager.PERMISSION_DENIED
                            ) {
                                someDenied = true
                            }
                        }
                    }
                    if (someDenied) {
                        settingActivityOpen()
                    }else{
                        showDialogOK { _: DialogInterface?, which: Int ->
                            when (which) {
                                DialogInterface.BUTTON_POSITIVE -> checkMultipleRequestPermissions()
                                DialogInterface.BUTTON_NEGATIVE -> { }
                            }
                        }
                    }
                }
            }
        }
}
 private fun settingActivityOpen() {
        Toast.makeText(
            this,
            "Go to settings and enable permissions",
            Toast.LENGTH_LONG
        )
            .show()
        val i = Intent()
        i.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        i.addCategory(Intent.CATEGORY_DEFAULT)
        i.data = Uri.parse("package:$packageName")
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
        startActivity(i)
}
private fun showDialogOK(okListener: DialogInterface.OnClickListener) {
        MaterialAlertDialogBuilder(this)
            .setMessage("All Permission required for this app")
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", okListener)
            .create()
            .show()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM