Today we will see a simple Android Request Permission at Runtime Example. We have already covered this topic before. But the previous way of requesting permissions in runtime is obsolete. In this post, we will see the most updated way of requesting runtime permission.
You can also check the old way of requesting runtime permissions.
But the new method is very, very easy, and simplified.
Now, let’s start our project without wasting any more time.
Table of Contents
Android Request Permission at Runtime Example
As always, we will create a new project using an Empty Activity. Once you are done creating your project, we can start adding the required dependencies.
Adding Dependencies
Here is the app level build.gradle file of my project.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 30 buildToolsVersion "30.0.2" defaultConfig { applicationId "net.simplifiedcoding.androidpermissions" minSdkVersion 21 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } //Adding Java8 Compile Options compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8.toString() } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' //These dependencies are required implementation "androidx.activity:activity:1.2.0-alpha08" implementation 'androidx.fragment:fragment:1.3.0-alpha08' } |
Here we need to add Java8 compile options, as the new things require some Java8 features. Also, we have added two dependencies that will simplify requesting permission.
Declaring Permission in AndroidManifest.xml
We also need to declare all the permissions required in AndroidManifest.xml file.
1 2 3 |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
Designing UI
As it is just an example; we will create a very simple UI. Below you can see what I have designed.
So design is very simple; we only have a couple of TextViews and a Button. (Don’t worry if you have any problem; you can get the complete source code at the end of this post).
We are halfway done for this Android Request Permission at Runtime Example. I will create an extension function to show an explanation alert to the user that why do we need this permission.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fun Context.showPermissionRequestExplanation( permission: String, message: String, retry: (() -> Unit)? = null ) { AlertDialog.Builder(this).apply { setTitle("$permission Required") setMessage(message) setPositiveButton("Ok") { _, _ -> retry?.invoke() } }.show() } |
Requesting Permission at Runtime
Now let’s request permission, and here is my MainActivit.kt .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
class MainActivity : AppCompatActivity() { // Step #1 // we need an instance of ActivityResultLauncher first private lateinit var requestPermissionLauncher: ActivityResultLauncher<String> @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Step #2 // we will save the instance by calling the function registerForActivityResult() // It takes ActivityResultContracts.RequestPermission() // And inside the trailing lambda we will get the callback // whenever user will allow or deny a permission // with the help of the boolean value inside the trailing lambda // we can check whether the permission was granted or not requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> textView.text = if (granted) { "Storage Permission Granted" //Here you can go with the action that requires permission //For now I am just showing a normal String in TextView } else { "Storage Permission NOT Granted" //Here you need to skip the functionality that requires permission //Because user has denied the permission //you can ask permission again when user will request the feature //that requires this permission } } button.setOnClickListener { // OnClick of the Button we will request the WRITE_EXTERNAL_STORAGE permission // It is just for the example you can request the permission that you requires // Step #3 // Request Permission requestStoragePermission() } } private fun requestStoragePermission(){ when { ContextCompat.checkSelfPermission( this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED -> { // The permission is granted // you can go with the flow that requires permission here } shouldShowRequestPermissionRationale(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) -> { // This case means user previously denied the permission // So here we can display an explanation to the user // That why exactly we need this permission showPermissionRequestExplanation( getString(R.string.write_storage), getString(R.string.permission_request) ) { requestPermissionLauncher.launch(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) } } else -> { // Everything is fine you can simply request the permission requestPermissionLauncher.launch(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) } } } } |
Here is the pseudocode to explain what needs to be done for asking permission.
- User requested a feature that requires a specific permission (For example we need to Save a File, and it requires Write Storage Permission).
- Check if that permission is already granted or not using
123ContextCompat.checkSelfPermission( this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED - If permission is granted; that’s it you can go with the flow.
- If permission is not already given; check whether user was previously asked for this permission or not using showPermissionRequestExplanation() function.
- If the permission was previously asked and denied by the user; show the user an explanation that why do this permission is needed.
- To request permission use
123requestPermissionLauncher.launch(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
That’s it. Easy Right?
Android Request Permission at Runtime Example Source Code
Still confused? You can check my source code here.
That is all for this Android Request Permission at Runtime Example. In case you have any confusion don’t hesitate to leave your comments below. Thank You 🙂