Android, запрос и проверка необходимых разрешений

При запуске приложения мне нужно проверять что у него есть все необходимые для работы разрешения. Это я делаю в onStart Activity следующим образом

try {
        val info = packageManager.getPackageInfo(this.packageName, PackageManager.GET_PERMISSIONS)
        Log.d(TAG, "SDK " + Build.VERSION.SDK_INT + " App Permissions:")
        if (info.requestedPermissions != null) {
            for (p in info.requestedPermissions) {
                val grantResult = this.checkPermission(p, android.os.Process.myPid(), android.os.Process.myUid())
                if (grantResult == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "$p PERMISSION_GRANTED")
                } else {
                    Log.d(TAG, "$p PERMISSION_DENIED: $grantResult")
                    val permissions = arrayOf(p)

                    ActivityCompat.requestPermissions(this, permissions,0)
                }
            }
        }

В LogCat я вижу что практически все разрешения есть, за исключением

Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,

По логике у меня должно в случае если нет разрешения, то должно появиться окно с запросом его. Однако окно не появляется.

В чем может быть проблема?


Ответы (1 шт):

Автор решения: Alex_Skvortsov

Код из вопроса действительно работает некорректно. Насколько я понимаю, не стоит запрашивать более одного разрешения одновременно. Во всяком случае, не таким образом.

На коленке написал код, на моем эмуляторе сработал:

companion object {
    private const val MY_PERMISSIONS_REQUEST_CODE = 1
}

private var listOfNonGrantedPermissions: MutableList<String> = mutableListOf()

override fun onStart() {
    super.onStart()
    val info = packageManager.getPackageInfo(this.packageName, PackageManager.GET_PERMISSIONS)
    Log.d(TAG, "SDK " + Build.VERSION.SDK_INT + " App Permissions:")
    info.requestedPermissions?.forEach {
        if (checkPermission(it, android.os.Process.myPid(), android.os.Process.myUid()) == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG,"$it PERMISSION_GRANTED")
        } else {
            Log.d(TAG,"$it PERMISSION_DENIED")
            listOfNonGrantedPermissions.add(it)
        }
    }
    makeRequestForNotGrantedPermissions()
}

private fun makeRequestForNotGrantedPermissions(){
    if (listOfNonGrantedPermissions.isNotEmpty()){
        val nextPermission = arrayOf(listOfNonGrantedPermissions.first())
        listOfNonGrantedPermissions.removeAt(0)
        ActivityCompat.requestPermissions(
            this,
            nextPermission,
            MY_PERMISSIONS_REQUEST_CODE
        )
    }
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    when (requestCode) {
        MY_PERMISSIONS_REQUEST_CODE -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG,"Granted") 
            } else {
                Log.d(TAG,"NOT Granted")
            }
            return makeRequestForNotGrantedPermissions()
        }
    }
}

Суть кода:

  1. Создаем список всех разрешений, которые не выданы.
  2. Вызываем функцию запроса разрешения.
  3. Функция запрашивает одно разрешение, если есть еще не полученные.
  4. Получив ответ от пользователя, снова вызываем функцию запроса разрешения.
  5. Если для всех разрешения ответ пользователя получен - процесс прекращается.

Код приведен для примера и с целью натолкнуть на действительное решение, использовать его в конечном варианте приложения не советую!

→ Ссылка