permissions.android.js 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // @flow
  2. import { AsyncStorage, NativeModules, PermissionsAndroid } from "react-native";
  3. type Status = "authorized" | "denied" | "restricted" | "undetermined";
  4. type Rationale = { title: string, message: string };
  5. type CheckOptions = string | { type: string };
  6. type RequestOptions = string | { type: string, rationale?: Rationale };
  7. const permissionTypes = {
  8. location: PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
  9. camera: PermissionsAndroid.PERMISSIONS.CAMERA,
  10. microphone: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
  11. contacts: PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
  12. event: PermissionsAndroid.PERMISSIONS.READ_CALENDAR,
  13. storage: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
  14. photo: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
  15. callPhone: PermissionsAndroid.PERMISSIONS.CALL_PHONE,
  16. readSms: PermissionsAndroid.PERMISSIONS.READ_SMS,
  17. receiveSms: PermissionsAndroid.PERMISSIONS.RECEIVE_SMS,
  18. };
  19. const RESULTS = {
  20. [PermissionsAndroid.RESULTS.GRANTED]: "authorized",
  21. [PermissionsAndroid.RESULTS.DENIED]: "denied",
  22. [PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN]: "restricted",
  23. };
  24. const STORAGE_KEY = "@RNPermissions:didAskPermission:";
  25. const setDidAskOnce = (permission: string) =>
  26. AsyncStorage.setItem(STORAGE_KEY + permission, "true");
  27. const getDidAskOnce = (permission: string) =>
  28. AsyncStorage.getItem(STORAGE_KEY + permission).then(item => !!item);
  29. class ReactNativePermissions {
  30. canOpenSettings: () => Promise<boolean> = () => Promise.resolve(false);
  31. openSettings: () => Promise<*> = () =>
  32. Promise.reject(new Error("'openSettings' is deprecated on android"));
  33. getTypes: () => Array<string> = () => Object.keys(permissionTypes);
  34. check = (permission: string, options?: CheckOptions): Promise<Status> => {
  35. if (!permissionTypes[permission]) {
  36. const error = new Error(
  37. `ReactNativePermissions: ${permission} is not a valid permission type on Android`,
  38. );
  39. return Promise.reject(error);
  40. }
  41. return PermissionsAndroid.check(permissionTypes[permission]).then(
  42. isAuthorized => {
  43. if (isAuthorized) {
  44. return "authorized";
  45. }
  46. return getDidAskOnce(permission).then(didAsk => {
  47. if (didAsk) {
  48. return NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale(
  49. permissionTypes[permission],
  50. ).then(shouldShow => (shouldShow ? "denied" : "restricted"));
  51. }
  52. return "undetermined";
  53. });
  54. },
  55. );
  56. };
  57. request = (permission: string, options?: RequestOptions): Promise<Status> => {
  58. if (!permissionTypes[permission]) {
  59. const error = new Error(
  60. `ReactNativePermissions: ${permission} is not a valid permission type on Android`,
  61. );
  62. return Promise.reject(error);
  63. }
  64. let rationale;
  65. if (options && options.rationale) {
  66. rationale = options.rationale;
  67. }
  68. return PermissionsAndroid.request(
  69. permissionTypes[permission],
  70. rationale,
  71. ).then(result => {
  72. // PermissionsAndroid.request() to native module resolves to boolean
  73. // rather than string if running on OS version prior to Android M
  74. if (typeof result === "boolean") {
  75. return result ? "authorized" : "denied";
  76. }
  77. return setDidAskOnce(permission).then(() => RESULTS[result]);
  78. });
  79. };
  80. checkMultiple = (permissions: Array<string>): Promise<{ [string]: string }> =>
  81. Promise.all(permissions.map(permission => this.check(permission))).then(
  82. result =>
  83. result.reduce((acc, value, index) => {
  84. const name = permissions[index];
  85. acc[name] = value;
  86. return acc;
  87. }, {}),
  88. );
  89. }
  90. export default new ReactNativePermissions();