Permission Handling - Android Studio - Compose
How to handle single & multiple runtime permissions
As we know we need to request Runtime Permissions on Android 6.0 (API level 23 also known as Marshmallow) and above as well as to declare them in the AndroidManifest file. If we need to use some features like Camera, Location, Contact, etc. we have to handle the runtime permissions. In this Tutorial, we will learn how to Request Single and Multiple Permissions.
Note: I'll add some permissions for example purposes only you may apply the same on permissions you want.
Code
AndroidManfiest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!--For Single Permission Example--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <!--For Multiple Permission Example--> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.CALL_PHONE"/> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> <activity android:name=".MainActivityCompose" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
MainActivity.kt
package com.technifysoft.myapplication import android.Manifest import android.os.Bundle import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.technifysoft.myapplication.ui.theme.MyApplicationTheme /** * MainActivityCompose is the main activity of the application, responsible for setting up the UI. */ class MainActivityCompose : ComponentActivity() { /** * Called when the activity is first created. This is where you should do all of your normal static set up: * create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's * previously frozen state, if there was one. */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyApplicationTheme { Scaffold( modifier = Modifier.fillMaxSize(), ) { innerPadding -> ReceiptScreen(innerPadding) } } } } } @Composable fun ReceiptScreen(innerPadding: PaddingValues) { val TAG = "PERMISSIONS_TAG" val context = LocalContext.current var resultText by remember { mutableStateOf("Result") } // Single permission launcher val singlePermissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestPermission() ) { isGranted -> Log.d(TAG, "Single Permission granted: $isGranted") if (isGranted) { resultText = "Single Permission granted. You can do your tasks..." } else { Toast.makeText(context, "Permission denied...", Toast.LENGTH_SHORT).show() } } // Multiple permissions launcher val multiplePermissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> var allGranted = true permissions.entries.forEach { entry -> Log.d(TAG, "${entry.key} granted: ${entry.value}") allGranted = allGranted && entry.value } if (allGranted) { resultText = "All Permissions granted. You can do your tasks..." } else { Toast.makeText(context, "All or some permissions denied...", Toast.LENGTH_SHORT).show() } } // UI Layout Column( modifier = Modifier.fillMaxSize().padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { // Title Text( text = "Permission handling", style = MaterialTheme.typography.headlineMedium ) Spacer(modifier = Modifier.height(20.dp)) // Single permission button Button( onClick = { singlePermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) }, modifier = Modifier.fillMaxWidth() ) { Text("Single Permission Request") } Spacer(modifier = Modifier.height(10.dp)) // Multiple permissions button Button( onClick = { multiplePermissionLauncher.launch( arrayOf( Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.CALL_PHONE ) ) }, modifier = Modifier.fillMaxWidth() ) { Text("Multiple Permission Request") } Spacer(modifier = Modifier.height(20.dp)) // Result text Text(text = resultText) } } /** * GreetingPreview is a composable function for previewing the MainUI in Android Studio. * It is annotated with @Preview to enable live preview. * */ @Preview(showBackground = true) @Composable fun GreetingPreview() { MyApplicationTheme { ReceiptScreen(PaddingValues()) } }
Comments
Post a Comment