20th June, 2022
In this example, You will learn how to handle the runtime permissions in Android.
Step 1: Create New Project
Create a new project in Android Studio from File ⇒ New Project and select Empty Activity from the templates.
Step 2: Add Permissions
Add required permissions to the AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Step 3: Handle Runtime Permissions
Create a util class and add following methods.
package com.codestringz.mytestapp; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import java.util.ArrayList; import java.util.List; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; public class Util { public static void requestPermissions(Context context, @NonNull String[] appPermissions, int reqCode) { List<String> listPermissionsNeeded = new ArrayList<>(); for (String permission : appPermissions) { if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(permission); } } if (!listPermissionsNeeded.isEmpty()) { ActivityCompat.requestPermissions((Activity) context, listPermissionsNeeded.toArray(new String[0]), reqCode); } } public static boolean isAllPermissionsGranted(Context context, @NonNull String[] appPermissions) { for (String permission : appPermissions) { if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } }
Add some strings to the strings.xml
<resources> <string name="app_name">My Test App</string> <string name="msg_yes_permissions_granted">Yes, Permissions Granted!</string> <string name="msg_everything_is_okay">Everything is okay!</string> <string name="msg_req_permission_try_again">Permission required for this app. Do you want to try again?</string> <string name="try_again">Try again?</string> <string name="msg_open_settings">Do you want to open app settings to enable required permissions?</string> <string name="tag_package">package</string> <string name="msg_permissions_granted_do_anything">Perms granted, do anything!</string> <string name="OK">OK</string> <string name="cancel">Cancel</string> <string name="request_permissions">Request Permissions</string> <string name="www_codestringz_com">www.CodestringZ.com</string> </resources>
Open the activity and request the runtime permissions.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/hintTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/www_codestringz_com" /> <Button android:id="@+id/testButton" android:text="@string/request_permissions" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp"/> </LinearLayout>
package com.codestringz.mytestapp; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private static final int CODE_MULTIPLE_PERMISSIONS = 558; private static final int CODE_APP_SETTING = CODE_MULTIPLE_PERMISSIONS + 1; //List of Permissions, You can add single permission as well private final String[] APP_PERMISSIONS = new String[] { Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, }; private TextView mHintTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setUIRef(); reqPermissions(); } private void setUIRef() { mHintTextView = findViewById(R.id.hintTextView); Button testButton = findViewById(R.id.testButton); testButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { reqPermissions(); } }); } private void reqPermissions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Util.isAllPermissionsGranted(this, APP_PERMISSIONS)) { //Permissions Granted mHintTextView.setText(getResources().getString(R.string.msg_yes_permissions_granted)); } else { //Permissions Not Granted Util.requestPermissions(MainActivity.this, APP_PERMISSIONS, CODE_MULTIPLE_PERMISSIONS); } } else { mHintTextView.setText(getResources().getString(R.string.msg_everything_is_okay)); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CODE_MULTIPLE_PERMISSIONS) { boolean allGranted = true; int nonGrantedPermissionIndex = -2; if (grantResults.length > 0) { for (int i = 0; i < grantResults.length; i++) { if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { allGranted = false; nonGrantedPermissionIndex = i; break; } } } if (!allGranted) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[nonGrantedPermissionIndex])) { //Show the dialog to grant the necessary permissions showDialogOK(getResources().getString(R.string.msg_req_permission_try_again), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_NEGATIVE: mHintTextView.setText(getResources().getString(R.string.try_again)); break; case DialogInterface.BUTTON_POSITIVE: //Request again Util.requestPermissions(getApplicationContext(), APP_PERMISSIONS, CODE_MULTIPLE_PERMISSIONS); break; } } }); } else { //Show the dialog to open app settings showDialogOK(getResources().getString(R.string.msg_open_settings), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_NEGATIVE: mHintTextView.setText(getResources().getString(R.string.try_again)); break; case DialogInterface.BUTTON_POSITIVE: Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts(getResources().getString(R.string.tag_package), getPackageName(), null); intent.setData(uri); startActivityForResult(intent, CODE_APP_SETTING); break; } } }); } } else { //All Granted, do anything! mHintTextView.setText(getResources().getString(R.string.msg_permissions_granted_do_anything)); } } } private void showDialogOK(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(MainActivity.this) .setMessage(message) .setPositiveButton(getResources().getString(R.string.OK), okListener) .setNegativeButton(getResources().getString(R.string.cancel), okListener) .create() .show(); } }
Happy coding!