123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // @flow
-
- import {NativeModules, PermissionsAndroid, Platform} from 'react-native';
- import AsyncStorage from '@react-native-community/async-storage';
- const NativeModule = NativeModules.ReactNativePermissions;
-
- export type PermissionStatus =
- | 'authorized'
- | 'denied'
- | 'restricted'
- | 'undetermined';
-
- export type Rationale = {
- title: string,
- message: string,
- buttonPositive?: string,
- buttonNegative?: string,
- buttonNeutral?: string,
- };
-
- const ASYNC_STORAGE_KEY = '@RNPermissions:didAskPermission:';
-
- const PERMISSIONS = Platform.select({
- ios: {
- backgroundRefresh: 'backgroundRefresh',
- bluetooth: 'bluetooth',
- camera: 'camera',
- contacts: 'contacts',
- event: 'event',
- location: 'location',
- mediaLibrary: 'mediaLibrary',
- microphone: 'microphone',
- motion: 'motion',
- notification: 'notification',
- photo: 'photo',
- reminder: 'reminder',
- speechRecognition: 'speechRecognition',
- },
- android: {
- callPhone: PermissionsAndroid.PERMISSIONS.CALL_PHONE,
- camera: PermissionsAndroid.PERMISSIONS.CAMERA,
- coarseLocation: PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
- contacts: PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
- event: PermissionsAndroid.PERMISSIONS.READ_CALENDAR,
- location: PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
- microphone: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
- photo: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
- readSms: PermissionsAndroid.PERMISSIONS.READ_SMS,
- receiveSms: PermissionsAndroid.PERMISSIONS.RECEIVE_SMS,
- sendSms: PermissionsAndroid.PERMISSIONS.SEND_SMS,
- storage: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
- },
- });
-
- const IOS_DEFAULT_OPTIONS = {
- location: 'whenInUse',
- notification: ['alert', 'badge', 'sound'],
- };
-
- const ANDROID_RESULTS = {
- granted: 'authorized',
- denied: 'denied',
- never_ask_again: 'restricted',
- };
-
- const setDidAskOnce = (permission: string) =>
- AsyncStorage.setItem(ASYNC_STORAGE_KEY + permission, 'true');
-
- const getDidAskOnce = (permission: string) =>
- AsyncStorage.getItem(ASYNC_STORAGE_KEY + permission).then(item => !!item);
-
- class ReactNativePermissions {
- canOpenSettings(): Promise<boolean> {
- return Platform.OS === 'ios'
- ? NativeModule.canOpenSettings().then(result => !!result)
- : Promise.resolve(false);
- }
-
- openSettings(): Promise<void> {
- return Platform.OS === 'ios'
- ? NativeModule.openSettings()
- : Promise.reject(new Error("'openSettings' is deprecated on android"));
- }
-
- getTypes(): string[] {
- return Object.keys(PERMISSIONS);
- }
-
- check = (
- permission: string,
- options?: string | {type?: string},
- ): Promise<PermissionStatus> => {
- if (!PERMISSIONS[permission]) {
- return Promise.reject(
- new Error(
- `ReactNativePermissions: ${permission} is not a valid permission type`,
- ),
- );
- }
-
- if (Platform.OS === 'ios') {
- let type = IOS_DEFAULT_OPTIONS[permission];
-
- if (typeof options === 'string') {
- type = options;
- } else if (options && options.type) {
- type = options.type;
- }
-
- return NativeModule.getPermissionStatus(permission, type);
- }
-
- if (Platform.OS === 'android') {
- return PermissionsAndroid.check(PERMISSIONS[permission]).then(granted => {
- if (granted) {
- return 'authorized';
- }
-
- return getDidAskOnce(permission).then(didAsk => {
- if (didAsk) {
- return NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale(
- PERMISSIONS[permission],
- ).then(shouldShow => (shouldShow ? 'denied' : 'restricted'));
- }
-
- return 'undetermined';
- });
- });
- }
-
- return Promise.resolve('restricted');
- };
-
- request = (
- permission: string,
- options?: string | {type?: string, rationale?: Rationale},
- ): Promise<PermissionStatus> => {
- if (!PERMISSIONS[permission]) {
- return Promise.reject(
- new Error(
- `ReactNativePermissions: ${permission} is not a valid permission type`,
- ),
- );
- }
-
- if (Platform.OS === 'ios') {
- if (permission == 'backgroundRefresh') {
- return Promise.reject(
- new Error(
- 'ReactNativePermissions: You cannot request backgroundRefresh',
- ),
- );
- }
-
- let type = IOS_DEFAULT_OPTIONS[permission];
-
- if (typeof options === 'string') {
- type = options;
- } else if (options && options.type) {
- type = options.type;
- }
-
- return NativeModule.requestPermission(permission, type);
- }
-
- if (Platform.OS === 'android') {
- let rationale: Rationale;
-
- if (typeof options === 'object' && options.rationale) {
- rationale = options.rationale;
- }
-
- return PermissionsAndroid.request(
- PERMISSIONS[permission],
- rationale,
- ).then(result => {
- // PermissionsAndroid.request() to native module resolves to boolean
- // rather than string if running on OS version prior to Android M
- if (typeof result === 'boolean') {
- return result ? 'authorized' : 'denied';
- }
-
- return setDidAskOnce(permission).then(() => ANDROID_RESULTS[result]);
- });
- }
-
- return Promise.resolve('restricted');
- };
-
- checkMultiple = (
- permissions: string[],
- ): Promise<{[permission: string]: PermissionStatus}> => {
- return Promise.all(
- permissions.map(permission => this.check(permission)),
- ).then(result =>
- result.reduce((acc, value, i) => {
- acc[permissions[i]] = value;
- return acc;
- }, {}),
- );
- };
- }
-
- export default new ReactNativePermissions();
|