Manage External Storage Permission | Android Studio | Kotlin

Manage External Storage Permission

Previously (before Android 11) we only need to request the WRITE_EXTERNAL_STORAGE Permission to perform the storage-related tasks. But, now for Android 11 and above we have to request the MANAGE_EXTERNAL_STORAGE Permission to perform the storage-related tasks. Keep in mind that if you're 100% sure that your app requires this permission to work properly then request this permission otherwise Google will not allow you to publish/update your app. For example, if your app is WhatsApp Status Saver then you won't be allowed to use this permission as your app works with images and videos, not files.
After permission is granted, I'll input a name and create a folder with that name just for example. You can do whatever you want instead.

>>Check For Java

Video Tutorial:


Coding:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.technifysoft.manageexternalstoragejava">

    <!--Permissions for the Android below 11 (R)-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--Permission for the Android 11 (R) and above-->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

    <!--Android 10 only requires android:requestLegacyExternalStorage="true"-->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/Theme.ManageExternalStorageJava">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp"
    tools:context=".MainActivity">

    <!--EditText: Input Folder Name-->
    <EditText
        android:id="@+id/folderNameEt"
        android:layout_width="match_parent"
        android:layout_marginTop="10dp"
        android:layout_height="wrap_content"
        android:hint="Folder Name..."/>

    <!--Button: Create folder-->
    <com.google.android.material.button.MaterialButton
        android:id="@+id/createFolderBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Create Folder"/>

</LinearLayout>

MainActivity.kt

package com.technifysoft.manageexternalstorage

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.widget.EditText
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.material.button.MaterialButton
import java.io.File
import java.lang.Exception

class MainActivity : AppCompatActivity() {

    //UI Views
    private lateinit var folderNameEt: EditText
    private lateinit var createFolderBtn: MaterialButton

    private companion object{
        //PERMISSION request constant, assign any value
        private const val STORAGE_PERMISSION_CODE = 100
        private const val TAG = "PERMISSION_TAG"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //init UI Views
        folderNameEt = findViewById(R.id.folderNameEt)
        createFolderBtn = findViewById(R.id.createFolderBtn)

        //handle click, create folder
        createFolderBtn.setOnClickListener {
            if (checkPermission()){
                Log.d(TAG, "onCreate: Permission already granted, create folder")
                createFolder()
            }
            else{
                Log.d(TAG, "onCreate: Permission was not granted, request")
                requestPermission()
            }
        }

    }

    private fun createFolder(){
        //folder name
        val folderName = folderNameEt.text.toString().trim()

        //create folder using name we just input
        val file = File("${Environment.getExternalStorageDirectory()}/$folderName")
        //create folder
        val folderCreated = file.mkdir()

        //show if folder created or not
        if (folderCreated) {
            toast("Folder Created: ${file.absolutePath}")
        } else {
            toast("Folder not created....")
        }
    }

    private fun requestPermission(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
            //Android is 11(R) or above
            try {
                Log.d(TAG, "requestPermission: try")
                val intent = Intent()
                intent.action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
                val uri = Uri.fromParts("package", this.packageName, null)
                intent.data = uri
                storageActivityResultLauncher.launch(intent)
            }
            catch (e: Exception){
                Log.e(TAG, "requestPermission: ", e)
                val intent = Intent()
                intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
                storageActivityResultLauncher.launch(intent)
            }
        }
        else{
            //Android is below 11(R)
            ActivityCompat.requestPermissions(this,
            arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE),
            STORAGE_PERMISSION_CODE
            )
        }
    }

    private val storageActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
        Log.d(TAG, "storageActivityResultLauncher: ")
        //here we will handle the result of our intent
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
            //Android is 11(R) or above
            if (Environment.isExternalStorageManager()){
                //Manage External Storage Permission is granted
                Log.d(TAG, "storageActivityResultLauncher: Manage External Storage Permission is granted")
                createFolder()
            }
            else{
                //Manage External Storage Permission is denied....
                Log.d(TAG, "storageActivityResultLauncher: Manage External Storage Permission is denied....")
                toast("Manage External Storage Permission is denied....")
            }
        }
        else{
            //Android is below 11(R)
        }
    }

    private fun checkPermission(): Boolean{
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
            //Android is 11(R) or above
            Environment.isExternalStorageManager()
        }
        else{
            //Android is below 11(R)
            val write = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            val read = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            write == PackageManager.PERMISSION_GRANTED && read == PackageManager.PERMISSION_GRANTED
        }
    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == STORAGE_PERMISSION_CODE){
            if (grantResults.isNotEmpty()){
                //check each permission if granted or not
                val write = grantResults[0] == PackageManager.PERMISSION_GRANTED
                val read = grantResults[1] == PackageManager.PERMISSION_GRANTED
                if (write && read){
                    //External Storage Permission granted
                    Log.d(TAG, "onRequestPermissionsResult: External Storage Permission granted")
                    createFolder()
                }
                else{
                    //External Storage Permission denied...
                    Log.d(TAG, "onRequestPermissionsResult: External Storage Permission denied...")
                    toast("External Storage Permission denied...")
                }
            }
        }
    }


    private fun toast(message: String){
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
}

Output

Manage External Storage Permission | Android Studio | Kotlin


Comments

Popular posts from this blog

Manage External Storage Permission | Android Studio | Java

Add a Back Button to Action Bar Android Studio (Kotlin)