UNPKG

react-native-permissions

Version:

An unified permissions API for React Native on iOS, Android and Windows

968 lines (806 loc) β€’ 37.9 kB
# ☝🏼 react-native-permissions An unified permissions API for React Native on iOS, Android and Windows.<br> (For Windows only builds 18362 and later are supported) [![mit licence](https://img.shields.io/dub/l/vibe-d.svg?style=for-the-badge)](https://github.com/zoontek/react-native-permissions/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/react-native-permissions?style=for-the-badge)](https://www.npmjs.org/package/react-native-permissions) [![npm downloads](https://img.shields.io/npm/dt/react-native-permissions.svg?label=downloads&style=for-the-badge)](https://www.npmjs.org/package/react-native-permissions) <br /> [![platform - android](https://img.shields.io/badge/platform-Android-3ddc84.svg?logo=android&style=for-the-badge)](https://www.android.com) [![platform - ios](https://img.shields.io/badge/platform-iOS-000.svg?logo=apple&style=for-the-badge)](https://developer.apple.com/ios) [![platform - windows](https://img.shields.io/badge/platform-Windows-0067b8.svg?logo=windows&style=for-the-badge)](https://www.microsoft.com/en-us/windows) ## Support This library follows the React Native [releases support policy](https://github.com/reactwg/react-native-releases#releases-support-policy).<br> It is supporting the **latest version**, and the **two previous minor series**. ## Setup ```bash $ npm install --save react-native-permissions # --- or --- $ yarn add react-native-permissions ``` ### iOS By default no permission handler is linked. To add one, update your `package.json` by adding the permissions used in your app, then run `npx react-native setup-ios-permissions` followed by `pod install` (`reactNativePermissionsIOS.json` is also supported). _πŸ“ŒΒ Β Note that these commands must be re-executed each time you update this config, delete the `node_modules` directory or update this library. An useful trick to cover a lot of these cases is running them on `postinstall` and just run `yarn` or `npm install` manually when needed._ ```json { "reactNativePermissionsIOS": [ "AppTrackingTransparency", "BluetoothPeripheral", "Calendars", "Camera", "Contacts", "FaceID", "LocationAccuracy", "LocationAlways", "LocationWhenInUse", "MediaLibrary", "Microphone", "Motion", "Notifications", "PhotoLibrary", "PhotoLibraryAddOnly", "Reminders", "Siri", "SpeechRecognition", "StoreKit" ], "devDependencies": { "pod-install": "0.1.38" }, "scripts": { "postinstall": "react-native setup-ios-permissions && pod-install" } } ``` Then update your `Info.plist` with wanted permissions usage descriptions: ```xml <?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>YOUR TEXT</string> <key>NSBluetoothAlwaysUsageDescription</key> <string>YOUR TEXT</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>YOUR TEXT</string> <key>NSCalendarsUsageDescription</key> <string>YOUR TEXT</string> <key>NSCameraUsageDescription</key> <string>YOUR TEXT</string> <key>NSContactsUsageDescription</key> <string>YOUR TEXT</string> <key>NSFaceIDUsageDescription</key> <string>YOUR TEXT</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>YOUR TEXT</string> <key>NSLocationAlwaysUsageDescription</key> <string>YOUR TEXT</string> <key>NSLocationTemporaryUsageDescriptionDictionary</key> <dict> <key>YOUR-PURPOSE-KEY</key> <string>YOUR TEXT</string> </dict> <key>NSLocationWhenInUseUsageDescription</key> <string>YOUR TEXT</string> <key>NSMicrophoneUsageDescription</key> <string>YOUR TEXT</string> <key>NSMotionUsageDescription</key> <string>YOUR TEXT</string> <key>NSPhotoLibraryUsageDescription</key> <string>YOUR TEXT</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>YOUR TEXT</string> <key>NSRemindersUsageDescription</key> <string>YOUR TEXT</string> <key>NSSpeechRecognitionUsageDescription</key> <string>YOUR TEXT</string> <key>NSSiriUsageDescription</key> <string>YOUR TEXT</string> <key>NSUserTrackingUsageDescription</key> <string>YOUR TEXT</string> <!-- … --> </dict> </plist> ``` ### Android Add all wanted permissions to your app `android/app/src/main/AndroidManifest.xml` file: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 🚨 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.ACCESS_MEDIA_LOCATION" /> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" /> <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" /> <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BODY_SENSORS" /> <uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" /> <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.NEARBY_WIFI_DEVICES" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <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_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <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.UWB_RANGING" /> <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" /> <!-- … --> </manifest> ``` ### Windows Open the project solution file from the `windows` folder. In the app project open `Package.appxmanifest` file. From there you can select which capabilites you want your app to support. ## πŸ†˜ Manual linking Because this package targets React Native 0.63.0+, you probably won't need to link it manually. Otherwise if it's not the case, follow these additional instructions. You also need to manual link the module on Windows when using React Native Windows prior to 0.63: <details> <summary><b>πŸ‘€ See manual linking instructions</b></summary> ### iOS Add this line to your `ios/Podfile` file, then run `pod install`. ```bash target 'YourAwesomeProject' do # … pod 'RNPermissions', :path => '../node_modules/react-native-permissions' end ``` ### Android 1. Add the following lines to `android/settings.gradle`: ```gradle include ':react-native-permissions' project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android') ``` 2. Add the implementation line to the dependencies in `android/app/build.gradle`: ```gradle dependencies { // ... implementation project(':react-native-permissions') } ``` 3. Add the import and link the package in `MainApplication.java`: ```java import com.zoontek.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; } // … } ``` ### Windows 1. In `windows/myapp.sln` add the `RNCConfig` project to your solution: - Open the solution in Visual Studio 2019 - Right-click Solution icon in Solution Explorer > Add > Existing Project - Select `node_modules\react-native-permissions\windows\RNPermissions\RNPermissions.vcxproj` 2. In `windows/myapp/myapp.vcxproj` ad a reference to `RNPermissions` to your main application project. From Visual Studio 2019: - Right-click main application project > Add > Reference... - Check `RNPermissions` from Solution Projects. 3. In `pch.h` add `#include "winrt/RNPermissions.h"`. 4. In `app.cpp` add `PackageProviders().Append(winrt::RNPermissions::ReactPackageProvider());` before `InitializeComponent();`. </details> ## Understanding permission flow 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, take a look to these two flowcharts: ### iOS flow ``` ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ check(PERMISSIONS.IOS.CAMERA) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ β”‚ Is the feature available on this deviceΒ ? β”‚ ╔════╗ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ NO ║──────────────┐ β”‚ β•šβ•β•β•β•β• β”‚ ╔═════╗ β–Ό β•‘ YES β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•šβ•β•β•β•β•β• β”‚ RESULTS.UNAVAILABLE β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Is the permission requestableΒ ? β”‚ ╔════╗ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ NO ║──────────────┐ β”‚ β•šβ•β•β•β•β• β”‚ ╔═════╗ β–Ό β•‘ YES β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•šβ•β•β•β•β•β• β”‚ RESULTS.BLOCKED / β”‚ β”‚ β”‚ RESULTS.LIMITED / β”‚ β”‚ β”‚ RESULTS.GRANTED β”‚ β–Ό β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RESULTS.DENIED β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ request(PERMISSIONS.IOS.CAMERA) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ β”‚ Does the user accept the requestΒ ? β”‚ ╔════╗ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ NO ║──────────────┐ β”‚ β•šβ•β•β•β•β• β”‚ ╔═════╗ β–Ό β•‘ YES β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•šβ•β•β•β•β•β• β”‚ RESULTS.BLOCKED β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RESULTS.GRANTED β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Android flow ``` ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ check(PERMISSIONS.ANDROID.CAMERA) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ β”‚ Is the feature available on this deviceΒ ? β”‚ ╔════╗ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ NO ║──────────────┐ β”‚ β•šβ•β•β•β•β• β”‚ ╔═════╗ β–Ό β•‘ YES β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•šβ•β•β•β•β•β• β”‚ RESULTS.UNAVAILABLE β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Is the permission already granted ? β”‚ ╔═════╗ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ YES ║─────────────┐ β”‚ β•šβ•β•β•β•β•β• β”‚ ╔════╗ β–Ό β•‘ NO β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•šβ•β•β•β•β• β”‚ RESULTS.GRANTED β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RESULTS.DENIED │◀──────────────────────┐ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β–Ό β”‚ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ╔═════╗ ┃ request(PERMISSIONS.ANDROID.CAMERA) ┃ β•‘ YES β•‘ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ β•šβ•β•β•β•β•β• β”‚ β”‚ Does the user accept β”‚ the requestΒ ? β”‚ β”‚ ╔════╗ Is the permission β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ NO ║──── still requestableΒ ? β”‚ β•šβ•β•β•β•β• β”‚ ╔═════╗ ╔════╗ β•‘ YES β•‘ β•‘ NO β•‘ β•šβ•β•β•β•β•β• β•šβ•β•β•β•β• β”‚ β”‚ β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RESULTS.GRANTED β”‚ β”‚ RESULTS.BLOCKED β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Windows flow ``` ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ check(PERMISSIONS.WINDOWS.WEBCAM) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ β”‚ 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.WINDOWS.WEBCAM) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ β”‚ Does the user accept the requestΒ ? β”‚ ╔════╗ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β•‘ NO ║──────────────┐ β”‚ β•šβ•β•β•β•β• β”‚ ╔═════╗ β–Ό β•‘ YES β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•šβ•β•β•β•β•β• β”‚ RESULTS.BLOCKED β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RESULTS.GRANTED β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## API ### Supported permissions <details> <summary><b>Android permissions</b></summary> ```js import {PERMISSIONS} from 'react-native-permissions'; PERMISSIONS.ANDROID.ACCEPT_HANDOVER; PERMISSIONS.ANDROID.ACCESS_BACKGROUND_LOCATION; PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION; PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION; PERMISSIONS.ANDROID.ACCESS_MEDIA_LOCATION; PERMISSIONS.ANDROID.ACTIVITY_RECOGNITION; PERMISSIONS.ANDROID.ADD_VOICEMAIL; PERMISSIONS.ANDROID.ANSWER_PHONE_CALLS; PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE; PERMISSIONS.ANDROID.BLUETOOTH_CONNECT; PERMISSIONS.ANDROID.BLUETOOTH_SCAN; PERMISSIONS.ANDROID.BODY_SENSORS; PERMISSIONS.ANDROID.BODY_SENSORS_BACKGROUND; PERMISSIONS.ANDROID.CALL_PHONE; PERMISSIONS.ANDROID.CAMERA; PERMISSIONS.ANDROID.GET_ACCOUNTS; PERMISSIONS.ANDROID.NEARBY_WIFI_DEVICES; PERMISSIONS.ANDROID.POST_NOTIFICATIONS; 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_MEDIA_AUDIO; PERMISSIONS.ANDROID.READ_MEDIA_IMAGES; PERMISSIONS.ANDROID.READ_MEDIA_VIDEO; 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.UWB_RANGING; PERMISSIONS.ANDROID.WRITE_CALENDAR; PERMISSIONS.ANDROID.WRITE_CALL_LOG; PERMISSIONS.ANDROID.WRITE_CONTACTS; PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE; ``` </details> <details> <summary><b>iOS permissions</b></summary> ```js import {PERMISSIONS} from 'react-native-permissions'; PERMISSIONS.IOS.APP_TRACKING_TRANSPARENCY; 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.PHOTO_LIBRARY_ADD_ONLY; PERMISSIONS.IOS.REMINDERS; PERMISSIONS.IOS.SIRI; PERMISSIONS.IOS.SPEECH_RECOGNITION; PERMISSIONS.IOS.STOREKIT; ``` </details> <details> <summary><b>Windows permissions</b></summary> ```js import {PERMISSIONS} from 'react-native-permissions'; PERMISSIONS.WINDOWS.ACCESSORY_MANAGER; PERMISSIONS.WINDOWS.ACTIVITY; PERMISSIONS.WINDOWS.ALLOW_ELEVATION; PERMISSIONS.WINDOWS.ALL_APP_MODS; PERMISSIONS.WINDOWS.ALL_JOYN; PERMISSIONS.WINDOWS.APPOINTMENTS; PERMISSIONS.WINDOWS.APPOINTMENTS_SYSTEM; PERMISSIONS.WINDOWS.APP_BROADCAST_SERVICES; PERMISSIONS.WINDOWS.APP_CAPTURE_SERVICES; PERMISSIONS.WINDOWS.APP_CAPTURE_SETTINGS; PERMISSIONS.WINDOWS.APP_DIAGNOSTICS; PERMISSIONS.WINDOWS.APP_LICENSING; PERMISSIONS.WINDOWS.AUDIO_DEVICE_CONFIGURATION; PERMISSIONS.WINDOWS.BACKGROUND_MEDIA_PLAYBACK; PERMISSIONS.WINDOWS.BACKGROUND_MEDIA_RECORDING; PERMISSIONS.WINDOWS.BACKGROUND_SPATIAL_PERCEPTION; PERMISSIONS.WINDOWS.BACKGROUND_VOIP; PERMISSIONS.WINDOWS.BLOCKED_CHAT_MESSAGES; PERMISSIONS.WINDOWS.BLUETOOTH; PERMISSIONS.WINDOWS.BROAD_FILE_SYSTEM_ACCESS; PERMISSIONS.WINDOWS.CAMERA_PROCESSING_EXTENSION; PERMISSIONS.WINDOWS.CELLULAR_DEVICE_CONTROL; PERMISSIONS.WINDOWS.CELLULAR_DEVICE_IDENTITY; PERMISSIONS.WINDOWS.CELLULAR_MESSAGING; PERMISSIONS.WINDOWS.CHAT_SYSTEM; PERMISSIONS.WINDOWS.CODE_GENERATION; PERMISSIONS.WINDOWS.CONFIRM_APP_CLOSE; PERMISSIONS.WINDOWS.CONTACTS; PERMISSIONS.WINDOWS.CONTACTS_SYSTEM; PERMISSIONS.WINDOWS.CORTANA_PERMISSIONS; PERMISSIONS.WINDOWS.CORTANA_SPEECH_ACCESSORY; PERMISSIONS.WINDOWS.CUSTOM_INSTALL_ACTIONS; PERMISSIONS.WINDOWS.DEVELOPMENT_MODE_NETWORK; PERMISSIONS.WINDOWS.DEVICE_MANAGEMENT_DM_ACCOUNT; PERMISSIONS.WINDOWS.DEVICE_MANAGEMENT_EMAIL_ACCOUNT; PERMISSIONS.WINDOWS.DEVICE_MANAGEMENT_FOUNDATION; PERMISSIONS.WINDOWS.DEVICE_MANAGEMENT_WAP_SECURITY_POLICIES; PERMISSIONS.WINDOWS.DEVICE_PORTAL_PROVIDER; PERMISSIONS.WINDOWS.DEVICE_UNLOCK; PERMISSIONS.WINDOWS.DOCUMENTS_LIBRARY; PERMISSIONS.WINDOWS.DUAL_SIM_TILES; PERMISSIONS.WINDOWS.EMAIL; PERMISSIONS.WINDOWS.EMAIL_SYSTEM; PERMISSIONS.WINDOWS.ENTERPRISE_AUTHENTICATION; PERMISSIONS.WINDOWS.ENTERPRISE_CLOUD_S_S_O; PERMISSIONS.WINDOWS.ENTERPRISE_DATA_POLICY; PERMISSIONS.WINDOWS.ENTERPRISE_DEVICE_LOCKDOWN; PERMISSIONS.WINDOWS.EXPANDED_RESOURCES; PERMISSIONS.WINDOWS.EXTENDED_BACKGROUND_TASK_TIME; PERMISSIONS.WINDOWS.EXTENDED_EXECUTION_BACKGROUND_AUDIO; PERMISSIONS.WINDOWS.EXTENDED_EXECUTION_CRITICAL; PERMISSIONS.WINDOWS.EXTENDED_EXECUTION_UNCONSTRAINED; PERMISSIONS.WINDOWS.FIRST_SIGN_IN_SETTINGS; PERMISSIONS.WINDOWS.GAME_BAR_SERVICES; PERMISSIONS.WINDOWS.GAME_LIST; PERMISSIONS.WINDOWS.GAME_MONITOR; PERMISSIONS.WINDOWS.GAZE_INPUT; PERMISSIONS.WINDOWS.GLOBAL_MEDIA_CONTROL; PERMISSIONS.WINDOWS.HUMANINTERFACEDEVICE; PERMISSIONS.WINDOWS.INPUT_FOREGROUND_OBSERVATION; PERMISSIONS.WINDOWS.INPUT_INJECTION_BROKERED; PERMISSIONS.WINDOWS.INPUT_OBSERVATION; PERMISSIONS.WINDOWS.INPUT_SUPPRESSION; PERMISSIONS.WINDOWS.INTERNET_CLIENT; PERMISSIONS.WINDOWS.INTERNET_CLIENT_SERVER; PERMISSIONS.WINDOWS.INTEROP_SERVICES; PERMISSIONS.WINDOWS.IOT; PERMISSIONS.WINDOWS.LOCAL_SYSTEM_SERVICES; PERMISSIONS.WINDOWS.LOCATION; PERMISSIONS.WINDOWS.LOCATION_HISTORY; PERMISSIONS.WINDOWS.LOCATION_SYSTEM; PERMISSIONS.WINDOWS.LOW_LEVEL; PERMISSIONS.WINDOWS.LOW_LEVEL_DEVICES; PERMISSIONS.WINDOWS.MICROPHONE; PERMISSIONS.WINDOWS.MOBILE; PERMISSIONS.WINDOWS.MODIFIABLE_APP; PERMISSIONS.WINDOWS.MUSIC_LIBRARY; PERMISSIONS.WINDOWS.NETWORKING_VPN_PROVIDER; PERMISSIONS.WINDOWS.NETWORK_CONNECTION_MANAGER_PROVISIONING; PERMISSIONS.WINDOWS.NETWORK_DATA_PLAN_PROVISIONING; PERMISSIONS.WINDOWS.NETWORK_DATA_USAGE_MANAGEMENT; PERMISSIONS.WINDOWS.OEM_DEPLOYMENT; PERMISSIONS.WINDOWS.OEM_PUBLIC_DIRECTORY; PERMISSIONS.WINDOWS.ONE_PROCESS_VOIP; PERMISSIONS.WINDOWS.OPTICAL; PERMISSIONS.WINDOWS.PACKAGED_SERVICES; PERMISSIONS.WINDOWS.PACKAGES_SERVICES; PERMISSIONS.WINDOWS.PACKAGE_MANAGEMENT; PERMISSIONS.WINDOWS.PACKAGE_POLICY_SYSTEM; PERMISSIONS.WINDOWS.PACKAGE_QUERY; PERMISSIONS.WINDOWS.PACKAGE_WRITE_REDIRECTION_COMPATIBILITY_SHIM; PERMISSIONS.WINDOWS.PHONE_CALL; PERMISSIONS.WINDOWS.PHONE_CALL_HISTORY; PERMISSIONS.WINDOWS.PHONE_CALL_HISTORY_SYSTEM; PERMISSIONS.WINDOWS.PHONE_LINE_TRANSPORT_MANAGEMENT; PERMISSIONS.WINDOWS.PICTURES_LIBRARY; PERMISSIONS.WINDOWS.POINT_OF_SERVICE; PERMISSIONS.WINDOWS.PREVIEW_INK_WORKSPACE; PERMISSIONS.WINDOWS.PREVIEW_PEN_WORKSPACE; PERMISSIONS.WINDOWS.PREVIEW_STORE; PERMISSIONS.WINDOWS.PREVIEW_UI_COMPOSITION; PERMISSIONS.WINDOWS.PRIVATE_NETWORK_CLIENT_SERVER; PERMISSIONS.WINDOWS.PROTECTED_APP; PERMISSIONS.WINDOWS.PROXIMITY; PERMISSIONS.WINDOWS.RADIOS; PERMISSIONS.WINDOWS.RECORDED_CALLS_FOLDER; PERMISSIONS.WINDOWS.REMOTE_PASSPORT_AUTHENTICATION; PERMISSIONS.WINDOWS.REMOTE_SYSTEM; PERMISSIONS.WINDOWS.REMOVABLE_STORAGE; PERMISSIONS.WINDOWS.RESCAP; PERMISSIONS.WINDOWS.RUN_FULL_TRUST; PERMISSIONS.WINDOWS.SCREEN_DUPLICATION; PERMISSIONS.WINDOWS.SECONDARY_AUTHENTICATION_FACTOR; PERMISSIONS.WINDOWS.SECURE_ASSESSMENT; PERMISSIONS.WINDOWS.SERIALCOMMUNICATION; PERMISSIONS.WINDOWS.SHARED_USER_CERTIFICATES; PERMISSIONS.WINDOWS.SLAPI_QUERY_LICENSE_VALUE; PERMISSIONS.WINDOWS.SMBIOS; PERMISSIONS.WINDOWS.SMS_SEND; PERMISSIONS.WINDOWS.SPATIAL_PERCEPTION; PERMISSIONS.WINDOWS.START_SCREEN_MANAGEMENT; PERMISSIONS.WINDOWS.STORE_LICENSE_MANAGEMENT; PERMISSIONS.WINDOWS.SYSTEM_MANAGEMENT; PERMISSIONS.WINDOWS.TARGETED_CONTENT; PERMISSIONS.WINDOWS.TEAM_EDITION_DEVICE_CREDENTIAL; PERMISSIONS.WINDOWS.TEAM_EDITION_EXPERIENCE; PERMISSIONS.WINDOWS.TEAM_EDITION_VIEW; PERMISSIONS.WINDOWS.UAP; PERMISSIONS.WINDOWS.UI_AUTOMATION; PERMISSIONS.WINDOWS.UNVIRTUALIZED_RESOURCES; PERMISSIONS.WINDOWS.USB; PERMISSIONS.WINDOWS.USER_ACCOUNT_INFORMATION; PERMISSIONS.WINDOWS.USER_DATA_ACCOUNTS_PROVIDER; PERMISSIONS.WINDOWS.USER_DATA_SYSTEM; PERMISSIONS.WINDOWS.USER_PRINCIPAL_NAME; PERMISSIONS.WINDOWS.USER_SYSTEM_ID; PERMISSIONS.WINDOWS.VIDEOS_LIBRARY; PERMISSIONS.WINDOWS.VOIP_CALL; PERMISSIONS.WINDOWS.WALLET_SYSTEM; PERMISSIONS.WINDOWS.WEBCAM; PERMISSIONS.WINDOWS.WIFI_CONTROL; PERMISSIONS.WINDOWS.XBOX_ACCESSORY_MANAGEMENT; ``` </details> ### Permissions statuses Permission checks and requests 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.LIMITED` | The permission is granted but with limitations | | `RESULTS.BLOCKED` | The permission is denied and not requestable anymore | ### Methods ```ts // type used in usage examples type PermissionStatus = 'unavailable' | 'denied' | 'limited' | 'granted' | 'blocked'; ``` #### check Check one permission status. _⚠️  Android will never return `blocked` after a `check`, you have to request the permission to get the info._ ```ts function check(permission: string): Promise<PermissionStatus>; ``` ```js import {check, PERMISSIONS, RESULTS} from 'react-native-permissions'; check(PERMISSIONS.IOS.LOCATION_ALWAYS) .then((result) => { switch (result) { case RESULTS.UNAVAILABLE: console.log('This feature is not available (on this device / in this context)'); break; case RESULTS.DENIED: console.log('The permission has not been requested / is denied but requestable'); break; case RESULTS.LIMITED: console.log('The permission is limited: some actions are possible'); break; case RESULTS.GRANTED: console.log('The permission is granted'); break; case RESULTS.BLOCKED: console.log('The permission is denied and not requestable anymore'); break; } }) .catch((error) => { // … }); ``` --- #### request Request one permission. Note that the `rationale` parameter is only available and used on Android. ```ts type Rationale = { title: string; message: string; buttonPositive?: string; buttonNegative?: string; buttonNeutral?: string; }; function request(permission: string, rationale?: Rationale): Promise<PermissionStatus>; ``` ```js import {request, PERMISSIONS} from 'react-native-permissions'; request(PERMISSIONS.IOS.LOCATION_ALWAYS).then((result) => { // … }); ``` --- #### checkNotifications Check notifications permission status and get notifications settings values. ```ts type NotificationSettings = { // properties only available on iOS // unavailable settings will not be included in the response object alert?: boolean; badge?: boolean; sound?: boolean; carPlay?: boolean; criticalAlert?: boolean; provisional?: boolean; providesAppSettings?: boolean; lockScreen?: boolean; notificationCenter?: boolean; }; function checkNotifications(): Promise<{ status: PermissionStatus; settings: NotificationSettings; }>; ``` ```js import {checkNotifications} from 'react-native-permissions'; checkNotifications().then(({status, settings}) => { // … }); ``` --- #### requestNotifications Request notifications permission status and get notifications settings values. - You have to [target at least SDK 33](https://github.com/zoontek/react-native-permissions/releases/tag/3.5.0) to perform request on Android 13+. The permission is always granted for prior versions. - You cannot request notifications permissions on Windows. Disabling / enabling them can only be done through the App Settings. ```ts // only used on iOS type NotificationOption = | 'alert' | 'badge' | 'sound' | 'criticalAlert' | 'carPlay' | 'provisional' | 'providesAppSettings'; type NotificationSettings = { // properties only available on iOS // unavailable settings will not be included in the response object alert?: boolean; badge?: boolean; sound?: boolean; carPlay?: boolean; criticalAlert?: boolean; provisional?: boolean; providesAppSettings?: boolean; lockScreen?: boolean; notificationCenter?: boolean; }; function requestNotifications(options: NotificationOption[]): Promise<{ status: PermissionStatus; settings: NotificationSettings; }>; ``` ```js import {requestNotifications} from 'react-native-permissions'; requestNotifications(['alert', 'sound']).then(({status, settings}) => { // … }); ``` --- #### checkMultiple Check multiples permissions in parallel. _⚠️  Android will never return `blocked` after a `check`, you have to request the permission to get the info._ ```ts function checkMultiple<P extends Permission[]>( permissions: P, ): Promise<Record<P[number], PermissionStatus>>; ``` ```js import {checkMultiple, PERMISSIONS} from 'react-native-permissions'; checkMultiple([PERMISSIONS.IOS.CAMERA, PERMISSIONS.IOS.FACE_ID]).then((statuses) => { console.log('Camera', statuses[PERMISSIONS.IOS.CAMERA]); console.log('FaceID', statuses[PERMISSIONS.IOS.FACE_ID]); }); ``` --- #### requestMultiple Request multiple permissions in sequence. ```ts function requestMultiple<P extends Permission[]>( permissions: P, ): Promise<Record<P[number], PermissionStatus>>; ``` ```js import {requestMultiple, PERMISSIONS} from 'react-native-permissions'; requestMultiple([PERMISSIONS.IOS.CAMERA, PERMISSIONS.IOS.FACE_ID]).then((statuses) => { console.log('Camera', statuses[PERMISSIONS.IOS.CAMERA]); console.log('FaceID', statuses[PERMISSIONS.IOS.FACE_ID]); }); ``` --- #### openSettings Open application settings. ```ts function openSettings(): Promise<void>; ``` ```js import {openSettings} from 'react-native-permissions'; openSettings().catch(() => console.warn('cannot open settings')); ``` --- #### openLimitedPhotoLibraryPicker (iOS 14+) Open a picker to update the photo selection when `PhotoLibrary` permission is `limited`. This will reject if unsupported or if full permission is already `granted`. ```ts function openLimitedPhotoLibraryPicker(): Promise<void>; ``` ```js import {openLimitedPhotoLibraryPicker} from 'react-native-permissions'; openLimitedPhotoLibraryPicker().catch(() => { console.warn('Cannot open photo library picker'); }); ``` --- #### checkLocationAccuracy (iOS 14+) When `LocationAlways` or `LocationWhenInUse` is `granted`, allow checking if the user share his precise location. ```ts type LocationAccuracy = 'full' | 'reduced'; function checkLocationAccuracy(): Promise<LocationAccuracy>; ``` ```js import {checkLocationAccuracy} from 'react-native-permissions'; checkLocationAccuracy() .then((accuracy) => console.log(`Location accuracy is: ${accuracy}`)) .catch(() => console.warn('Cannot check location accuracy')); ``` --- #### requestLocationAccuracy (iOS 14+) When `LocationAlways` or `LocationWhenInUse` is `granted`, allow requesting the user for his precise location. Will resolve immediately if `full` accuracy is already authorized. ```ts type LocationAccuracyOptions = { purposeKey: string; }; type LocationAccuracy = 'full' | 'reduced'; function requestLocationAccuracy(options: LocationAccuracyOptions): Promise<LocationAccuracy>; ``` ```js import {requestLocationAccuracy} from 'react-native-permissions'; requestLocationAccuracy({purposeKey: 'YOUR-PURPOSE-KEY'}) .then((accuracy) => console.log(`Location accuracy is: ${accuracy}`)) .catch(() => console.warn('Cannot request location accuracy')); ``` ### About iOS `LOCATION_ALWAYS` permission If you are requesting `PERMISSIONS.IOS.LOCATION_ALWAYS`, there won't be a `Always Allow` button in the system dialog. Only `Allow Once`, `Allow While Using App` and `Don't Allow`. This is expected behaviour, check the [Apple Developer Docs](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620551-requestalwaysauthorization#3578736). When requesting `PERMISSIONS.IOS.LOCATION_ALWAYS`, if the user choose `Allow While Using App`, a provisional "always" status will be granted. The user will see `While Using` in the settings and later will be informed that your app is using the location in background. That looks like this: ![alt text](https://camo.githubusercontent.com/e8357168f4c8e754adfd940fc065520de838a21a80001839d5e740c18893ec67/68747470733a2f2f636d732e717a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031392f30392f696f732d31332d6c6f636174696f6e732d7465736c612d31393230783938322e6a70673f7175616c6974793d37352673747269703d616c6c26773d3132303026683d3930302663726f703d31 'Screenshot') Subsequently, if you are requesting `LOCATION_ALWAYS` permission, there is no need to request `LOCATION_WHEN_IN_USE`. If the user accepts, `LOCATION_WHEN_IN_USE` will be granted too. If the user denies, `LOCATION_WHEN_IN_USE` will be denied too. ### Testing with Jest If you don't already have a Jest setup file configured, please add the following to your Jest configuration file and create the new `jest.setup.js` file in project root: ```js setupFiles: ['<rootDir>/jest.setup.js']; ``` You can then add the following line to that setup file to mock the `NativeModule.RNPermissions`: ```js jest.mock('react-native-permissions', () => require('react-native-permissions/mock')); ``` ## Sponsors This module is provided **as is**, I work on it in my free time. If you or your company uses it in a production app, consider sponsoring this project πŸ’°. You also can contact me for **premium** enterprise support: help with issues, prioritize bugfixes, feature requests, etc. <a href="https://github.com/sponsors/zoontek"><img align="center" alt="Sponsors list" src="https://raw.githubusercontent.com/zoontek/sponsors/main/sponsorkit/sponsors.svg"></a>