Mathieu Acthernoene 583fc9cab2 Update example to RN 0.61.1 5 years ago
android Fix gradle setup 5 years ago
example Update example to RN 0.61.1 5 years ago
ios Replace CBPeripheralManager.authorizationStatus (deprecated) 5 years ago
src Return no supported permissions for platforms other than iOS / android 5 years ago
.editorconfig Fix gradle setup 5 years ago
.eslintignore Bump to 2.0.0-rc.0 5 years ago
.eslintrc.js Bump to 2.0.0-rc.0 5 years ago
.gitignore Update example to RN 0.61.1 5 years ago
.prettierignore Bump to 2.0.0-rc.0 5 years ago
.prettierrc Bump to 2.0.0-rc.0 5 years ago
.yarnrc Bump to 2.0.0-rc.0 5 years ago
CODEOWNERS Bump to 2.0.0-rc.0 5 years ago
LICENSE Bump to 2.0.0-rc.0 5 years ago
README.md Typo 5 years ago
RNPermissions.podspec Add tvOS deployment_target 5 years ago
package.json Fix gradle setup 5 years ago
tsconfig.json Bump to 2.0.0-rc.0 5 years ago
yarn.lock Fix gradle setup 5 years ago

README.md

โ˜๐Ÿผ React Native Permissions

npm version npm Platform - Android and iOS MIT styled with prettier

Check and request user permissions in React Native

Support

version react-native version
2.0.0+ 0.60.0+
1.1.1 0.40.0 - 0.52.2

For 2.0.0 with 0.59-, you can use jetify -r

Setup

$ npm install --save react-native-permissions@next
# --- or ---
$ yarn add react-native-permissions@next

iOS

By default no permission handler is installed. Update your Podfile by choosing the ones you want then run pod install.

target 'YourAwesomeProject' do

  # โ€ฆ

  permissions_path = '../node_modules/react-native-permissions/ios'

  pod 'Permission-BluetoothPeripheral', :path => "#{permissions_path}/BluetoothPeripheral.podspec"
  pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars.podspec"
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec"
  pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts.podspec"
  pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID.podspec"
  pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways.podspec"
  pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse.podspec"
  pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary.podspec"
  pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone.podspec"
  pod 'Permission-Motion', :path => "#{permissions_path}/Motion.podspec"
  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications.podspec"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary.podspec"
  pod 'Permission-Reminders', :path => "#{permissions_path}/Reminders.podspec"
  pod 'Permission-Siri', :path => "#{permissions_path}/Siri.podspec"
  pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition.podspec"
  pod 'Permission-StoreKit', :path => "#{permissions_path}/StoreKit.podspec"

end

Then update your Info.plist with wanted permissions usage descriptions.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

  <!-- ๐Ÿšจ keep only the permissions used in your app! ๐Ÿšจ -->

  <key>NSAppleMusicUsageDescription</key>
  <string>TEXT</string>
  <key>NSBluetoothAlwaysUsageDescription</key>
  <string>TEXT</string>
  <key>NSBluetoothPeripheralUsageDescription</key>
  <string>TEXT</string>
  <key>NSCalendarsUsageDescription</key>
  <string>TEXT</string>
  <key>NSCameraUsageDescription</key>
  <string>TEXT</string>
  <key>NSContactsUsageDescription</key>
  <string>TEXT</string>
  <key>NSFaceIDUsageDescription</key>
  <string>TEXT</string>
  <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
  <string>TEXT</string>
  <key>NSLocationAlwaysUsageDescription</key>
  <string>TEXT</string>
  <key>NSLocationWhenInUseUsageDescription</key>
  <string>TEXT</string>
  <key>NSMicrophoneUsageDescription</key>
  <string>TEXT</string>
  <key>NSMotionUsageDescription</key>
  <string>TEXT</string>
  <key>NSPhotoLibraryUsageDescription</key>
  <string>TEXT</string>
  <key>NSRemindersUsageDescription</key>
  <string>TEXT</string>
  <key>NSSpeechRecognitionUsageDescription</key>
  <string>TEXT</string>

  <!-- โ€ฆ -->

</dict>
</plist>

Android

Add all wanted permissions to your app android/app/src/main/res/AndroidManifest.xml.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.myawesomeapp">

  <!-- ๐Ÿšจ keep only the permissions used in your app! ๐Ÿšจ -->

  <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
  <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
  <uses-permission android:name="android.permission.BODY_SENSORS" />
  <uses-permission android:name="android.permission.CALL_PHONE" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.GET_ACCOUNTS" />
  <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
  <uses-permission android:name="android.permission.READ_CALENDAR" />
  <uses-permission android:name="android.permission.READ_CALL_LOG" />
  <uses-permission android:name="android.permission.READ_CONTACTS" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-permission android:name="android.permission.READ_SMS" />
  <uses-permission android:name="android.permission.RECEIVE_MMS" />
  <uses-permission android:name="android.permission.RECEIVE_SMS" />
  <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.SEND_SMS" />
  <uses-permission android:name="android.permission.USE_SIP" />
  <uses-permission android:name="android.permission.WRITE_CALENDAR" />
  <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
  <uses-permission android:name="android.permission.WRITE_CONTACTS" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />

  <!-- โ€ฆ -->

</manifest>

๐Ÿ†˜ Manual linking

Because this package targets React Native 0.60+, you will probably donโ€™t need to link it. Otherwise if you follow all the previous steps and it still doesnโ€™t work, try to link this library manually.

๐Ÿ‘€ See manual linking instructions

iOS

Add this line to your ios/Podfile file, then run pod install.

target 'YourAwesomeProject' do
  # โ€ฆ
  pod 'RNPermissions', :path => '../node_modules/react-native-permissions'
end

Android

  1. Add the following lines to android/settings.gradle:
include ':react-native-permissions'
project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')
  1. Add the implementation line to the dependencies in android/app/build.gradle:
dependencies {
  // ...
  implementation project(':react-native-permissions')
}
  1. Add the import and link the package in MainApplication.java:
import com.reactnativecommunity.rnpermissions.RNPermissionsPackage; // <- add the RNPermissionsPackage import

public class MainApplication extends Application implements ReactApplication {

  // โ€ฆ

  @Override
  protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
    // โ€ฆ
    packages.add(new RNPermissionsPackage());
    return packages;
  }

  // โ€ฆ
}

API

Permissions statuses

Promises resolve into one of these statuses:

Return value Notes
RESULTS.UNAVAILABLE This feature is not available (on this device / in this context)
RESULTS.DENIED The permission has not been requested / is denied but requestable
RESULTS.GRANTED The permission is granted
RESULTS.BLOCKED The permission is denied and not requestable anymore

Supported permissions

import {PERMISSIONS} from 'react-native-permissions';

// Android permissions

PERMISSIONS.ANDROID.ACCEPT_HANDOVER;
PERMISSIONS.ANDROID.ACCESS_BACKGROUND_LOCATION;
PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION;
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION;
PERMISSIONS.ANDROID.ACTIVITY_RECOGNITION;
PERMISSIONS.ANDROID.ADD_VOICEMAIL;
PERMISSIONS.ANDROID.ANSWER_PHONE_CALLS;
PERMISSIONS.ANDROID.BODY_SENSORS;
PERMISSIONS.ANDROID.CALL_PHONE;
PERMISSIONS.ANDROID.CAMERA;
PERMISSIONS.ANDROID.GET_ACCOUNTS;
PERMISSIONS.ANDROID.PROCESS_OUTGOING_CALLS;
PERMISSIONS.ANDROID.READ_CALENDAR;
PERMISSIONS.ANDROID.READ_CALL_LOG;
PERMISSIONS.ANDROID.READ_CONTACTS;
PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
PERMISSIONS.ANDROID.READ_PHONE_NUMBERS;
PERMISSIONS.ANDROID.READ_PHONE_STATE;
PERMISSIONS.ANDROID.READ_SMS;
PERMISSIONS.ANDROID.RECEIVE_MMS;
PERMISSIONS.ANDROID.RECEIVE_SMS;
PERMISSIONS.ANDROID.RECEIVE_WAP_PUSH;
PERMISSIONS.ANDROID.RECORD_AUDIO;
PERMISSIONS.ANDROID.SEND_SMS;
PERMISSIONS.ANDROID.USE_SIP;
PERMISSIONS.ANDROID.WRITE_CALENDAR;
PERMISSIONS.ANDROID.WRITE_CALL_LOG;
PERMISSIONS.ANDROID.WRITE_CONTACTS;
PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE;

// iOS permissions

PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL;
PERMISSIONS.IOS.CALENDARS;
PERMISSIONS.IOS.CAMERA;
PERMISSIONS.IOS.CONTACTS;
PERMISSIONS.IOS.FACE_ID;
PERMISSIONS.IOS.LOCATION_ALWAYS;
PERMISSIONS.IOS.LOCATION_WHEN_IN_USE;
PERMISSIONS.IOS.MEDIA_LIBRARY;
PERMISSIONS.IOS.MICROPHONE;
PERMISSIONS.IOS.MOTION;
PERMISSIONS.IOS.PHOTO_LIBRARY;
PERMISSIONS.IOS.REMINDERS;
PERMISSIONS.IOS.SIRI;
PERMISSIONS.IOS.SPEECH_RECOGNITION;
PERMISSIONS.IOS.STOREKIT;

Methods

types used in usage examples

type PermissionStatus = 'unavailable' | 'denied' | 'blocked' | 'granted';

check

Check one permission status.

function check(permission: string): Promise<PermissionStatus>;
import {check, PERMISSIONS, RESULTS} from 'react-native-permissions';

check(PERMISSIONS.IOS.LOCATION_ALWAYS)
  .then(result => {
    switch (result) {
      case RESULTS.UNAVAILABLE:
        console.log('the feature is not available');
        break;
      case RESULTS.GRANTED:
        console.log('permission is granted');
        break;
      case RESULTS.DENIED:
        console.log('permission is denied and / or requestable');
        break;
      case RESULTS.BLOCKED:
        console.log('permission is denied and not requestable');
        break;
    }
  })
  .catch(error => {
    // โ€ฆ
  });

request

Request one permission.

type Rationale = {
  title: string;
  message: string;
  buttonPositive?: string;
  buttonNegative?: string;
  buttonNeutral?: string;
};

function request(
  permission: string,
  rationale?: Rationale,
): Promise<PermissionStatus>;
import {request, PERMISSIONS} from 'react-native-permissions';

request(PERMISSIONS.IOS.LOCATION_ALWAYS).then(result => {
  // โ€ฆ
});

checkNotifications

Check notifications permission status and get settings values.

interface NotificationSettings {
  // properties only availables on iOS
  // unavailable settings will not be included in the response object
  alert?: boolean;
  badge?: boolean;
  sound?: boolean;
  lockScreen?: boolean;
  carPlay?: boolean;
  notificationCenter?: boolean;
  criticalAlert?: boolean;
}

function checkNotifications(): Promise<{
  status: PermissionStatus;
  settings: NotificationSettings;
}>;
import {checkNotifications} from 'react-native-permissions';

checkNotifications().then(({status, settings}) => {
  // โ€ฆ
});

requestNotifications

Request notifications permission status and get settings values.

// only used on iOS
type NotificationOption =
  | 'alert'
  | 'badge'
  | 'sound'
  | 'criticalAlert'
  | 'carPlay'
  | 'provisional';

interface NotificationSettings {
  // properties only availables on iOS
  // unavailable settings will not be included in the response object
  alert?: boolean;
  badge?: boolean;
  sound?: boolean;
  lockScreen?: boolean;
  carPlay?: boolean;
  notificationCenter?: boolean;
  criticalAlert?: boolean;
}

function requestNotifications(
  options: NotificationOption[],
): Promise<{
  status: PermissionStatus;
  settings: NotificationSettings;
}>;
import {requestNotifications} from 'react-native-permissions';

requestNotifications(['alert', 'sound']).then(({status, settings}) => {
  // โ€ฆ
});

openSettings

Open application settings.

function openSettings(): Promise<void>;
import {openSettings} from 'react-native-permissions';

openSettings().catch(() => console.warn('cannot open settings'));

Understanding lifecycle

As permissions are not handled in the same way on iOS and Android, this library provides an abstraction over the two platforms behaviors. To understand it a little better, have a look to these two flowcharts:

iOS

   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“
   โ”ƒ check(PERMISSIONS.IOS.CAMERA) โ”ƒ
   โ”—โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”›
                   โ”‚
       Is the feature available
           on this deviceย ?
                   โ”‚           โ•”โ•โ•โ•โ•โ•—
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ NO โ•‘โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚           โ•šโ•โ•โ•โ•โ•              โ”‚
                โ•”โ•โ•โ•โ•โ•โ•—                            โ–ผ
                โ•‘ YES โ•‘                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                โ•šโ•โ•โ•โ•โ•โ•                 โ”‚ RESULTS.UNAVAILABLE โ”‚
                   โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           Is the permission
             requestableย ?
                   โ”‚           โ•”โ•โ•โ•โ•โ•—
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ NO โ•‘โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚           โ•šโ•โ•โ•โ•โ•              โ”‚
                โ•”โ•โ•โ•โ•โ•โ•—                            โ–ผ
                โ•‘ YES โ•‘                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                โ•šโ•โ•โ•โ•โ•โ•                  โ”‚ RESULTS.BLOCKED / โ”‚
                   โ”‚                     โ”‚  RESULTS.GRANTED  โ”‚
                   โ–ผ                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚ RESULTS.DENIED โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
  โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“
  โ”ƒ request(PERMISSIONS.IOS.CAMERA) โ”ƒ
  โ”—โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”›
                   โ”‚
        Does the user accepted
            the requestย ?
                   โ”‚           โ•”โ•โ•โ•โ•โ•—
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ NO โ•‘โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚           โ•šโ•โ•โ•โ•โ•              โ”‚
                โ•”โ•โ•โ•โ•โ•โ•—                            โ–ผ
                โ•‘ YES โ•‘                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                โ•šโ•โ•โ•โ•โ•โ•                   โ”‚ RESULTS.BLOCKED โ”‚
                   โ”‚                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ–ผ
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚ RESULTS.GRANTED โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Android

 โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“
 โ”ƒ check(PERMISSIONS.ANDROID.CAMERA) โ”ƒ
 โ”—โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”›
                   โ”‚
       Is the feature available
           on this deviceย ?
                   โ”‚           โ•”โ•โ•โ•โ•โ•—
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ NO โ•‘โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚           โ•šโ•โ•โ•โ•โ•              โ”‚
                โ•”โ•โ•โ•โ•โ•โ•—                            โ–ผ
                โ•‘ YES โ•‘                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                โ•šโ•โ•โ•โ•โ•โ•                 โ”‚ RESULTS.UNAVAILABLE โ”‚
                   โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           Is the permission
             requestableย ?
                   โ”‚           โ•”โ•โ•โ•โ•โ•—
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ NO โ•‘โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚           โ•šโ•โ•โ•โ•โ•              โ”‚
                โ•”โ•โ•โ•โ•โ•โ•—                            โ–ผ
                โ•‘ YES โ•‘                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                โ•šโ•โ•โ•โ•โ•โ•                  โ”‚ RESULTS.BLOCKED / โ”‚
                   โ”‚                     โ”‚  RESULTS.GRANTED  โ”‚
                   โ–ผ                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚ RESULTS.DENIED โ”‚โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                       โ”‚
                   โ”‚                               โ”‚
                   โ–ผ                               โ”‚
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“         โ•”โ•โ•โ•โ•โ•—
โ”ƒ request(PERMISSIONS.ANDROID.CAMERA) โ”ƒ         โ•‘ NO โ•‘
โ”—โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”›         โ•šโ•โ•โ•โ•โ•
                   โ”‚                               โ”‚
        Does the user accepted                     โ”‚
            the requestย ?                          โ”‚
                   โ”‚           โ•”โ•โ•โ•โ•โ•—    Does the user checked
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•‘ NO โ•‘โ”€โ”€โ”€โ”€โ”€"Neverย askย again"ย ?
                   โ”‚           โ•šโ•โ•โ•โ•โ•              โ”‚
                โ•”โ•โ•โ•โ•โ•โ•—                         โ•”โ•โ•โ•โ•โ•โ•—
                โ•‘ YES โ•‘                         โ•‘ YES โ•‘
                โ•šโ•โ•โ•โ•โ•โ•                         โ•šโ•โ•โ•โ•โ•โ•
                   โ”‚                               โ”‚
                   โ–ผ                               โ–ผ
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚ RESULTS.GRANTED โ”‚             โ”‚ RESULTS.BLOCKED โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜