Search code examples
androidkotlingradle

Android: Run Time Permissions not working - App Settings Showing No Requested Permissions even when asked for (WRITE_EXTERNAL_STORAGE)


I'm working a background remover app from an image and upon the background removal process, I am supposed to download it to the download's folder butI keep getting the exception that no such file name found. So i tried asking for runtime permissions before downloading and i am facing an issue where my Android app is not showing the requested permissions in the app settings. I've declared the android.permission.WRITE_EXTERNAL_STORAGE permission in my AndroidManifest.xml and am requesting it at runtime using ActivityCompat.requestPermissions.

Despite this, the app settings page doesn't list the permission as requested. I've tried the following:

My build.gradle (app) file has minSdk set to 24 and targetSdk set to 34 and in my AndroidManifest file i have set targetApi to 31 and I am testing it on my OnePlus 12R device.

In order to ask for runtime permissions I am using the following code :

private fun requestRuntimePermissions() {
        when {
            ContextCompat.checkSelfPermission(
                this@ImageStaging,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) == PackageManager.PERMISSION_GRANTED -> {
                // You can use the API that requires the permission.
                Log.d("PermGrant", "Permission already granted...")
            }
            ActivityCompat.shouldShowRequestPermissionRationale(
                this@ImageStaging, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) -> {
                val builder = AlertDialog.Builder(this@ImageStaging)
                builder.setMessage("Permission to write is required to download the image to your storage...")
                builder.setTitle("Permission Required").setCancelable(false).setPositiveButton("OK", DialogInterface.OnClickListener { dialog, which ->
                    ActivityCompat.requestPermissions(this@ImageStaging, arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), writepermcode)
                    dialog.dismiss()
                })
                builder.setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, which ->
                    dialog.dismiss()
                })
                builder.show()

            }
            else -> {
                // You can directly ask for the permission.
                // The registered ActivityResultCallback gets the result of this request.
                ActivityCompat.requestPermissions(this@ImageStaging, arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), writepermcode)
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int,
                                            permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            writepermcode -> {
                // If request is cancelled, the result arrays are empty.
                if ((grantResults.isNotEmpty() &&
                            grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    // Permission is granted. Continue the action or workflow
                    // in your app.
                    Toast.makeText(this@ImageStaging, "Permission Granted!", Toast.LENGTH_SHORT).show()
                } else if (!ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    // Explain to the user that the feature is unavailable because
                    // the feature requires a permission that the user has denied.
                    // At the same time, respect the user's decision. Don't link to
                    // system settings in an effort to convince the user to change
                    // their decision.
                    val builder = AlertDialog.Builder(this@ImageStaging)
                    builder.setMessage("Permission to write is required to download the image to your storage...")
                    builder.setTitle("Permission Required").setCancelable(false).setPositiveButton("OK", DialogInterface.OnClickListener { dialog, which ->
                        val intent: Intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        val uri: Uri = Uri.fromParts("package", packageName, null)
                        intent.setData(uri)
                        startActivity(intent)
                        dialog.dismiss()
                    })
                    builder.setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, which ->
                        dialog.dismiss()
                    })
                    builder.show()
                }
                return
            }

            // Add other 'when' lines to check for other
            // permissions this app might request.
            else -> {
                // Ignore all other requests.
                requestRuntimePermissions()
            }
        }
    }

Upon running the app on my device i am expecting to see the app having requested at least a single external storage request, but i am getting the following output :

enter image description here


Solution

  • Handle permissions for android 13 and above.

    private fun checkStoragePermission(): Boolean {
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            val audioPermission = ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_MEDIA_AUDIO
            )
        
             val videoPermission = ContextCompat.checkSelfPermission(
                 this,
                 Manifest.permission.READ_MEDIA_VIDEO
             )
        
             val imagePermission = ContextCompat.checkSelfPermission(
                 this,
                 Manifest.permission.READ_MEDIA_IMAGES
             )
             return audioPermission == PackageManager.PERMISSION_GRANTED && videoPermission == PackageManager.PERMISSION_GRANTED && imagePermission == PackageManager.PERMISSION_GRANTED
        } else {
            val storagePermission = ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
            val courseLocationPermission = ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_EXTERNAL_STORAGE
            )
            return storagePermission == PackageManager.PERMISSION_GRANTED && courseLocationPermission == PackageManager.PERMISSION_GRANTED
        }
    }
    

    And add these lines in manfest.

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>