Browse Source

breaking changes - use RN's own JS PermissionsAndroid.

Yonah Forst 7 years ago
parent
commit
306e6928c1

+ 20
- 14
Example/Example.js View File

@@ -24,8 +24,10 @@ export default class Example extends Component {
24 24
   }
25 25
 
26 26
   componentDidMount() {
27
-    let types = Permissions.getPermissionTypes()
28
-    this.setState({ types })
27
+    let types = Permissions.getTypes()
28
+    let canOpenSettings = Permissions.canOpenSettings()
29
+
30
+    this.setState({ types, canOpenSettings })
29 31
     this._updatePermissions(types)
30 32
     AppState.addEventListener('change', this._handleAppStateChange.bind(this));
31 33
   }
@@ -47,10 +49,10 @@ export default class Example extends Component {
47 49
   }
48 50
 
49 51
   _updatePermissions(types) {
50
-    Permissions.checkMultiplePermissions(types)
52
+    Permissions.checkMultiple(types)
51 53
       .then(status => {
52 54
         if (this.state.isAlways) {
53
-          return Permissions.getPermissionStatus('location', 'always')
55
+          return Permissions.check('location', 'always')
54 56
             .then(location => ({...status, location}))
55 57
         }
56 58
         return status
@@ -65,19 +67,19 @@ export default class Example extends Component {
65 67
       options = this.state.isAlways ? 'always' : 'whenInUse'
66 68
     }
67 69
 
68
-    Permissions.requestPermission(permission, options)
70
+    Permissions.request(permission, options)
69 71
       .then(res => {
70 72
         this.setState({
71 73
           status: {...this.state.status, [permission]: res}
72 74
         })
73 75
         if (res != 'authorized') {
76
+          var buttons = [{ text: 'Cancel', style: 'cancel' }]
77
+          if (this.state.canOpenSettings) buttons.push({ text: 'Open Settings', onPress: this._openSettings.bind(this) })
78
+          
74 79
           Alert.alert(
75 80
             'Whoops!',
76 81
             "There was a problem getting your permission. Please enable it from settings.",
77
-            [
78
-              {text: 'Cancel', style: 'cancel'},
79
-              {text: 'Open Settings', onPress: this._openSettings.bind(this) },
80
-            ]
82
+            buttons
81 83
           )
82 84
         }
83 85
       }).catch(e => console.warn(e))
@@ -114,11 +116,15 @@ export default class Example extends Component {
114 116
             onPress={this._onLocationSwitchChange.bind(this)}>
115 117
             <Text style={styles.text}>Toggle location type</Text>
116 118
           </TouchableHighlight>
119
+   
120
+          {
121
+            this.state.canOpenSettings &&
122
+            <TouchableHighlight 
123
+              onPress={this._openSettings.bind(this)}>
124
+              <Text style={styles.text}>Open settings</Text>
125
+            </TouchableHighlight>
126
+          }
117 127
 
118
-          <TouchableHighlight 
119
-            onPress={this._openSettings.bind(this)}>
120
-            <Text style={styles.text}>Open settings</Text>
121
-          </TouchableHighlight>
122 128
         </View>
123 129
 
124 130
 
@@ -163,7 +169,7 @@ const styles = StyleSheet.create({
163 169
     backgroundColor: '#ef9a9a',
164 170
   },
165 171
   restricted: {
166
-    backgroundColor: '#FFAB91'
172
+    backgroundColor: '#ef9a9a'
167 173
   },
168 174
   footer: {
169 175
     padding: 10,

+ 0
- 1
Example/android/app/build.gradle View File

@@ -126,7 +126,6 @@ android {
126 126
 }
127 127
 
128 128
 dependencies {
129
-    compile project(':react-native-permissions')
130 129
     compile fileTree(dir: "libs", include: ["*.jar"])
131 130
     compile "com.android.support:appcompat-v7:23.0.1"
132 131
     compile "com.facebook.react:react-native:+"  // From node_modules

+ 0
- 1
Example/android/app/src/main/java/com/example/MainActivity.java View File

@@ -1,7 +1,6 @@
1 1
 package com.example;
2 2
 
3 3
 import com.facebook.react.ReactActivity;
4
-import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage;
5 4
 
6 5
 public class MainActivity extends ReactActivity {
7 6
 

+ 1
- 3
Example/android/app/src/main/java/com/example/MainApplication.java View File

@@ -8,7 +8,6 @@ import com.facebook.react.ReactInstanceManager;
8 8
 import com.facebook.react.ReactNativeHost;
9 9
 import com.facebook.react.ReactPackage;
10 10
 import com.facebook.react.shell.MainReactPackage;
11
-import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage;
12 11
 import com.facebook.soloader.SoLoader;
13 12
 
14 13
 import java.util.Arrays;
@@ -25,8 +24,7 @@ public class MainApplication extends Application implements ReactApplication {
25 24
     @Override
26 25
     protected List<ReactPackage> getPackages() {
27 26
       return Arrays.<ReactPackage>asList(
28
-          new MainReactPackage(),
29
-          new ReactNativePermissionsPackage()
27
+          new MainReactPackage()
30 28
       );
31 29
     }
32 30
   };

+ 0
- 2
Example/android/settings.gradle View File

@@ -1,5 +1,3 @@
1 1
 rootProject.name = 'Example'
2 2
 
3 3
 include ':app'
4
-include ':react-native-permissions'
5
-project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')

+ 26
- 14
Example/ios/Example.xcodeproj/project.pbxproj View File

@@ -22,7 +22,6 @@
22 22
 		13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
23 23
 		140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
24 24
 		146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
25
-		14902CDAB1064113A6B4C970 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B27CA08432F04FFCB0256EA1 /* libReactNativePermissions.a */; };
26 25
 		2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
27 26
 		2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
28 27
 		2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
@@ -36,6 +35,7 @@
36 35
 		2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
37 36
 		2DCD954D1E0B4F2C00145EB5 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ExampleTests.m */; };
38 37
 		5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
38
+		6D05A8F55CC4482AACFFC932 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DF4131A2930454297EF564B /* libReactNativePermissions.a */; };
39 39
 		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
40 40
 /* End PBXBuildFile section */
41 41
 
@@ -229,9 +229,9 @@
229 229
 			remoteGlobalIDString = 58B5119B1A9E6C1200147676;
230 230
 			remoteInfo = RCTText;
231 231
 		};
232
-		9D8131C41E44834800F4B1D3 /* PBXContainerItemProxy */ = {
232
+		9D140CBB1F068EB400146F6C /* PBXContainerItemProxy */ = {
233 233
 			isa = PBXContainerItemProxy;
234
-			containerPortal = 8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */;
234
+			containerPortal = 1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */;
235 235
 			proxyType = 2;
236 236
 			remoteGlobalIDString = 9D23B34F1C767B80008B4819;
237 237
 			remoteInfo = ReactNativePermissions;
@@ -258,13 +258,13 @@
258 258
 		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = "<group>"; };
259 259
 		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = "<group>"; };
260 260
 		146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
261
+		1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; };
261 262
 		2D02E47B1E0B4A5D006451C7 /* Example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
262 263
 		2D02E4901E0B4A5D006451C7 /* Example-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
264
+		5DF4131A2930454297EF564B /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = "<group>"; };
263 265
 		5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
264 266
 		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
265
-		8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; };
266 267
 		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
267
-		B27CA08432F04FFCB0256EA1 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = "<group>"; };
268 268
 /* End PBXFileReference section */
269 269
 
270 270
 /* Begin PBXFrameworksBuildPhase section */
@@ -291,7 +291,7 @@
291 291
 				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
292 292
 				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
293 293
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
294
-				14902CDAB1064113A6B4C970 /* libReactNativePermissions.a in Frameworks */,
294
+				6D05A8F55CC4482AACFFC932 /* libReactNativePermissions.a in Frameworks */,
295 295
 			);
296 296
 			runOnlyForDeploymentPostprocessing = 0;
297 297
 		};
@@ -458,7 +458,7 @@
458 458
 				832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
459 459
 				00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
460 460
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
461
-				8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */,
461
+				1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */,
462 462
 			);
463 463
 			name = Libraries;
464 464
 			sourceTree = "<group>";
@@ -495,10 +495,10 @@
495 495
 			name = Products;
496 496
 			sourceTree = "<group>";
497 497
 		};
498
-		9D8131A81E44834700F4B1D3 /* Products */ = {
498
+		9D140C9F1F068EB400146F6C /* Products */ = {
499 499
 			isa = PBXGroup;
500 500
 			children = (
501
-				9D8131C51E44834800F4B1D3 /* libReactNativePermissions.a */,
501
+				9D140CBC1F068EB400146F6C /* libReactNativePermissions.a */,
502 502
 			);
503 503
 			name = Products;
504 504
 			sourceTree = "<group>";
@@ -584,7 +584,7 @@
584 584
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
585 585
 			isa = PBXProject;
586 586
 			attributes = {
587
-				LastUpgradeCheck = 0820;
587
+				LastUpgradeCheck = 820;
588 588
 				ORGANIZATIONNAME = Facebook;
589 589
 				TargetAttributes = {
590 590
 					00E356ED1AD99517003FC87E = {
@@ -666,8 +666,8 @@
666 666
 					ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
667 667
 				},
668 668
 				{
669
-					ProductGroup = 9D8131A81E44834700F4B1D3 /* Products */;
670
-					ProjectRef = 8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */;
669
+					ProductGroup = 9D140C9F1F068EB400146F6C /* Products */;
670
+					ProjectRef = 1CB53DB705894AAA8CB22783 /* ReactNativePermissions.xcodeproj */;
671 671
 				},
672 672
 			);
673 673
 			projectRoot = "";
@@ -856,11 +856,11 @@
856 856
 			remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
857 857
 			sourceTree = BUILT_PRODUCTS_DIR;
858 858
 		};
859
-		9D8131C51E44834800F4B1D3 /* libReactNativePermissions.a */ = {
859
+		9D140CBC1F068EB400146F6C /* libReactNativePermissions.a */ = {
860 860
 			isa = PBXReferenceProxy;
861 861
 			fileType = archive.ar;
862 862
 			path = libReactNativePermissions.a;
863
-			remoteRef = 9D8131C41E44834800F4B1D3 /* PBXContainerItemProxy */;
863
+			remoteRef = 9D140CBB1F068EB400146F6C /* PBXContainerItemProxy */;
864 864
 			sourceTree = BUILT_PRODUCTS_DIR;
865 865
 		};
866 866
 /* End PBXReferenceProxy section */
@@ -1007,6 +1007,8 @@
1007 1007
 				LIBRARY_SEARCH_PATHS = (
1008 1008
 					"$(inherited)",
1009 1009
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1010
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1011
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1010 1012
 				);
1011 1013
 				OTHER_LDFLAGS = (
1012 1014
 					"-ObjC",
@@ -1028,6 +1030,8 @@
1028 1030
 				LIBRARY_SEARCH_PATHS = (
1029 1031
 					"$(inherited)",
1030 1032
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1033
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1034
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1031 1035
 				);
1032 1036
 				OTHER_LDFLAGS = (
1033 1037
 					"-ObjC",
@@ -1090,6 +1094,8 @@
1090 1094
 				LIBRARY_SEARCH_PATHS = (
1091 1095
 					"$(inherited)",
1092 1096
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1097
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1098
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1093 1099
 				);
1094 1100
 				OTHER_LDFLAGS = (
1095 1101
 					"-ObjC",
@@ -1120,6 +1126,8 @@
1120 1126
 				LIBRARY_SEARCH_PATHS = (
1121 1127
 					"$(inherited)",
1122 1128
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1129
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1130
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1123 1131
 				);
1124 1132
 				OTHER_LDFLAGS = (
1125 1133
 					"-ObjC",
@@ -1149,6 +1157,8 @@
1149 1157
 				LIBRARY_SEARCH_PATHS = (
1150 1158
 					"$(inherited)",
1151 1159
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1160
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1161
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1152 1162
 				);
1153 1163
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1154 1164
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1174,6 +1184,8 @@
1174 1184
 				LIBRARY_SEARCH_PATHS = (
1175 1185
 					"$(inherited)",
1176 1186
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1187
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1188
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1177 1189
 				);
1178 1190
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1179 1191
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 2
- 0
Example/ios/Example/Info.plist View File

@@ -51,6 +51,8 @@
51 51
 	<string>test</string>
52 52
 	<key>NSRemindersUsageDescription</key>
53 53
 	<string>test</string>
54
+	<key>NSSpeechRecognitionUsageDescription</key>
55
+	<string>test</string>
54 56
 	<key>UIBackgroundModes</key>
55 57
 	<array>
56 58
 		<string>bluetooth-peripheral</string>

+ 17
- 66
README.md View File

@@ -17,6 +17,7 @@ The current supported permissions are:
17 17
 
18 18
 | Version | React Native Support |
19 19
 |---|---|
20
+| 1.0.0 | 0.40.0 - 0.45.0 |
20 21
 | 0.2.7 | 0.40.0 - 0.41.0 |
21 22
 | 0.2.5 | 0.33.0 - 0.39.0 |
22 23
 *Complies with [react-native-version-support-table](https://github.com/dangnelson/react-native-version-support-table)*
@@ -94,7 +95,7 @@ Promises resolve into one of these statuses
94 95
 |---|---|
95 96
 |`authorized`| user has authorized this permission |
96 97
 |`denied`| user has denied this permission at least once. On iOS this means that the user will not be prompted again. Android users can be promted multiple times until they select 'Never ask me again'|
97
-|`restricted`| *(iOS only)* user is not able to grant this permission, either because it's not supported by the device or because it has been blocked by parental controls. |
98
+|`restricted`| **iOS** - this means user is not able to grant this permission, either because it's not supported by the device or because it has been blocked by parental controls. **Android** - this means that the user has selected 'Never ask me again' while denying permission |
98 99
 |`undetermined`| user has not yet been prompted with a permission dialog |
99 100
 
100 101
 ### Supported permission types
@@ -117,33 +118,32 @@ Promises resolve into one of these statuses
117 118
 ### Methods
118 119
 | Method Name | Arguments | Notes
119 120
 |---|---|---|
120
-| `getPermissionStatus` | `type` | - Returns a promise with the permission status. See iOS Notes for special cases |
121
-| `requestPermission` | `type` | - Accepts any permission type except `backgroundRefresh`. If the current status is `undetermined`, shows the permission dialog and returns a promise with the resulting status. Otherwise, immediately return a promise with the current status. See iOS Notes for special cases|
122
-| `checkMultiplePermissions` | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses |
123
-| `getPermissionTypes` | *none* | - Returns an array of valid permission types  |
124
-| `openSettings` | *none* | - Switches the user to the settings page of your app (iOS 8.0 and later)  |
125
-| `canOpenSettings` | *none* | - Returns a boolean indicating if the device supports switching to the settings page |
121
+| `check` | `type` | - Returns a promise with the permission status. See iOS Notes for special cases |
122
+| `request` | `type` | - Accepts any permission type except `backgroundRefresh`. If the current status is `undetermined`, shows the permission dialog and returns a promise with the resulting status. Otherwise, immediately return a promise with the current status. See iOS Notes for special cases|
123
+| `checkMultiple` | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses |
124
+| `getTypes` | *none* | - Returns an array of valid permission types  |
125
+| `openSettings` | *none* | - *(iOS only - 8.0 and later)* Switches the user to the settings page of your app |
126
+| `canOpenSettings` | *none* | - *(iOS only)* Returns a boolean indicating if the device supports switching to the settings page |
126 127
 
127 128
 ### iOS Notes
128
-Permission type `bluetooth` represents the status of the `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
129
+- Permission type `bluetooth` represents the status of the `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
130
+- Permission type `location` accepts a second parameter for `requestPermission` and `getPermissionStatus`;  the second parameter is a string, either `always` or `whenInUse`(default).
129 131
 
130
-Permission type `location` accepts a second parameter for `requestPermission` and `getPermissionStatus`;  the second parameter is a string, either `always` or `whenInUse`(default).
131
-
132
-Permission type `notification` accepts a second parameter for `requestPermission`. The second parameter is an array with the desired alert types. Any combination of `alert`, `badge` and `sound` (default requests all three)
132
+- Permission type `notification` accepts a second parameter for `requestPermission`. The second parameter is an array with the desired alert types. Any combination of `alert`, `badge` and `sound` (default requests all three)
133 133
 
134 134
 ```js
135 135
 ///example
136
-    Permissions.getPermissionStatus('location', 'always')
136
+    Permissions.check('location', 'always')
137 137
       .then(response => {
138 138
         this.setState({ locationPermission: response })
139 139
       })
140 140
 
141
-    Permissions.requestPermission('location', 'always')
141
+    Permissions.request('location', 'always')
142 142
       .then(response => {
143 143
         this.setState({ locationPermission: response })
144 144
       })
145 145
 
146
-    Permissions.requestPermission('notification', ['alert', 'badge'])
146
+    Permissions.request('notification', ['alert', 'badge'])
147 147
       .then(response => {
148 148
         this.setState({ notificationPermission: response })
149 149
       })
@@ -161,20 +161,12 @@ If you need Contacts permission you have to add the key "Privacy - Contacts Usag
161 161
 
162 162
 Requires RN >= 0.29.0
163 163
 
164
+Uses RN's own `PermissionsAndroid` JS api (http://facebook.github.io/react-native/releases/0.45/docs/permissionsandroid.html)
165
+
164 166
 All required permissions also need to be included in the Manifest before they can be requested. Otherwise `requestPermission` will immediately return `denied`.
165 167
 
166 168
 Permissions are automatically accepted for targetSdkVersion < 23 but you can still use `getPermissionStatus` to check if the user has disabled them from Settings.
167 169
 
168
-Here's a map of types to Android system permissions names:
169
-`location` -> `android.permission.ACCESS_FINE_LOCATION`
170
-`camera` -> `android.permission.CAMERA`
171
-`microphone` -> `android.permission.RECORD_AUDIO`
172
-`photo` -> `android.permission.READ_EXTERNAL_STORAGE`
173
-`storage` -> `android.permission.READ_EXTERNAL_STORAGE`
174
-`contacts` -> `android.permission.READ_CONTACTS`
175
-`event` -> `android.permission.READ_CALENDAR`
176
-
177
-
178 170
 You can request write access to any of these types by also including the appropriate write permission in the Manifest. Read more here: https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
179 171
 
180 172
 ## Setup
@@ -192,46 +184,8 @@ rnpm link
192 184
 * Add libReactNativePermissions.a to `Build Phases -> Link Binary With Libraries.
193 185
 
194 186
 #### Android
195
-##### Step 1 - Update Gradle Settings
196
-
197
-```
198
-// file: android/settings.gradle
199
-...
200
-
201
-include ':react-native-permissions'
202
-project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')
203
-```
204
-##### Step 2 - Update Gradle Build
205
-
206
-```
207
-// file: android/app/build.gradle
208
-...
209
-
210
-dependencies {
211
-    ...
212
-    compile project(':react-native-permissions')
213
-}
214
-```
215
-##### Step 3 - Register React Package
216
-```
217
-...
218
-import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage; // <--- import
219
-
220
-public class MainApplication extends Application implements ReactApplication {
187
+  No additional linking required
221 188
 
222
-    ...
223
-
224
-    @Override
225
-    protected List<ReactPackage> getPackages() {
226
-        return Arrays.<ReactPackage>asList(
227
-            new MainReactPackage(),
228
-            new ReactNativePermissionsPackage() // <------ add the package
229
-        );
230
-    }
231
-
232
-    ...
233
-}
234
-```
235 189
 ## AppStore submission disclaimer
236 190
 
237 191
 If you need to submit you application to the AppStore, you need to add to your `Info.plist` all `*UsageDescription` keys with a string value explaining to the user how the app uses this data. **Even if you don't use them**.
@@ -261,9 +215,6 @@ You can find more informations about this issue in #46.
261 215
 
262 216
 ## Troubleshooting
263 217
 
264
-#### Q: Android - `undefined is not a object (evaluating 'RNPermissions.requestPermissions')`
265
-A: `rnpm` may not have linked correctly. Follow the manual linking steps and make sure the library is linked
266
-
267 218
 #### Q: iOS - app crashes as soon as I request permission
268 219
 A: starting with xcode 8, you need to add permission descriptions. see iOS notes for more details. Thanks to @jesperlndk for discovering this.
269 220
 

+ 0
- 116
ReactNativePermissions.js View File

@@ -1,116 +0,0 @@
1
-'use strict';
2
-
3
-var ReactNative = require('react-native')
4
-var Platform = ReactNative.Platform
5
-var RNPermissions = ReactNative.NativeModules.ReactNativePermissions;
6
-
7
-const RNPTypes = {
8
-	ios: [
9
-		'location',
10
-		'camera',
11
-		'microphone',
12
-		'photo',
13
-		'contacts',
14
-		'event',
15
-		'reminder',
16
-		'bluetooth',
17
-		'notification',
18
-		'backgroundRefresh',
19
-		'speechRecognition',
20
-	],
21
-	android: [
22
-		'location',
23
-		'camera',
24
-		'microphone',
25
-		'contacts',
26
-		'event',
27
-		'photo',
28
-		'storage',
29
-		'notification',
30
-	]
31
-}
32
-
33
-class ReactNativePermissions {
34
-	constructor() {
35
-		//legacy support
36
-		this.StatusUndetermined = 'undetermined'
37
-		this.StatusDenied = 'denied'
38
-		this.StatusAuthorized = 'authorized'
39
-		this.StatusRestricted = 'restricted'
40
-
41
-		this.getPermissionTypes().forEach(type => {
42
-			let methodName = `${type}PermissionStatus`
43
-			this[methodName] = p => {
44
-				console.warn(`ReactNativePermissions: ${methodName} is depricated. Use getPermissionStatus('${type}') instead.`)
45
-				return this.getPermissionStatus(p == 'reminder' ? p : type)
46
-			}
47
-		})
48
-	}
49
-
50
-	canOpenSettings() {
51
-		return RNPermissions.canOpenSettings()
52
-	}
53
-
54
-	openSettings() {
55
-		return RNPermissions.openSettings()
56
-	}
57
-
58
-	getPermissionTypes() {
59
-		return RNPTypes[Platform.OS];
60
-	}
61
-
62
-
63
-	getPermissionStatus(permission, type) {
64
-  	if (this.getPermissionTypes().indexOf(permission) >= 0) {
65
-			return RNPermissions.getPermissionStatus(permission, type)
66
-		} else {
67
-			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on ${Platform.OS}`)
68
-		}
69
-	}
70
-
71
-	requestPermission(permission, type) {
72
-		let options;
73
-
74
-		if (this.getPermissionTypes().indexOf(permission) === -1) {
75
-			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on ${Platform.OS}`)
76
-		} else if (permission == 'backgroundRefresh'){
77
-			return Promise.reject('ReactNativePermissions: You cannot request backgroundRefresh')
78
-		} else if (permission == 'location') {
79
-			options = type || 'whenInUse'
80
-		} else if (permission == 'notification') {
81
-			if (Platform.OS === 'android') {
82
-				return Promise.reject(`ReactNativePermissions: notification cannot be requested on Android`)
83
-			}
84
-			options = type || ['alert', 'badge', 'sound']
85
-		}
86
-
87
-		return RNPermissions.requestPermission(permission, options)
88
-	}
89
-
90
-	//recursive funciton to chain a promises for a list of permissions
91
-	checkMultiplePermissions(permissions) {
92
-		let i = permissions.length
93
-		let that = this
94
-		const obj = {}
95
-		function processNext() {
96
-			i--
97
-			let p = permissions[i]
98
-
99
-			if (!p) {
100
-				return Promise.resolve(obj)
101
-			}
102
-
103
-			return that.getPermissionStatus(p)
104
-				.then(res => {
105
-					obj[p] = res
106
-					return processNext()
107
-				}).catch(e => {
108
-					console.warn(e)
109
-					return processNext()
110
-				})
111
-		}
112
-		return processNext()
113
-	}
114
-}
115
-
116
-module.exports = new ReactNativePermissions()

+ 0
- 34
android/build.gradle View File

@@ -1,34 +0,0 @@
1
-buildscript {
2
-    repositories {
3
-        jcenter()
4
-    }
5
-
6
-    dependencies {
7
-        classpath 'com.android.tools.build:gradle:2.1.+'
8
-    }
9
-}
10
-
11
-apply plugin: 'com.android.library'
12
-
13
-android {
14
-    compileSdkVersion 24
15
-    buildToolsVersion "25.0.2"
16
-
17
-    defaultConfig {
18
-        minSdkVersion 16
19
-        targetSdkVersion 24
20
-        versionCode 1
21
-        versionName "1.0"
22
-    }
23
-    lintOptions {
24
-        abortOnError false
25
-    }
26
-}
27
-
28
-repositories {
29
-    jcenter()
30
-}
31
-
32
-dependencies {
33
-    compile 'com.facebook.react:react-native:+'
34
-}

+ 0
- 3
android/src/main/AndroidManifest.xml View File

@@ -1,3 +0,0 @@
1
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
-    package="com.joshblour.reactnativepermissions">
3
-</manifest>

+ 0
- 154
android/src/main/java/com/joshblour/reactnativepermissions/ReactNativePermissionsModule.java View File

@@ -1,154 +0,0 @@
1
-package com.joshblour.reactnativepermissions;
2
-
3
-import android.Manifest;
4
-import android.content.Intent;
5
-import android.net.Uri;
6
-import android.provider.Settings;
7
-import android.support.v4.app.ActivityCompat;
8
-import android.support.v4.app.NotificationManagerCompat;
9
-import android.support.v4.content.ContextCompat;
10
-import android.support.v4.content.PermissionChecker;
11
-
12
-import com.facebook.react.bridge.Callback;
13
-import com.facebook.react.bridge.Promise;
14
-import com.facebook.react.bridge.PromiseImpl;
15
-import com.facebook.react.bridge.ReactApplicationContext;
16
-import com.facebook.react.bridge.ReactContextBaseJavaModule;
17
-import com.facebook.react.bridge.ReactMethod;
18
-import com.facebook.react.bridge.ReadableMap;
19
-import com.facebook.react.bridge.ReadableArray;
20
-import com.facebook.react.modules.permissions.PermissionsModule;
21
-
22
-import java.util.Locale;
23
-
24
-public class ReactNativePermissionsModule extends ReactContextBaseJavaModule {
25
-  private final ReactApplicationContext reactContext;
26
-  private final PermissionsModule mPermissionsModule;
27
-  private final NotificationManagerCompat mNotificationManagerCompat;
28
-
29
-  public enum RNType {
30
-    LOCATION,
31
-    NOTIFICATION,
32
-    CAMERA,
33
-    MICROPHONE,
34
-    CONTACTS,
35
-    EVENT,
36
-    STORAGE,
37
-    PHOTO;
38
-  }
39
-
40
-  public ReactNativePermissionsModule(ReactApplicationContext reactContext) {
41
-    super(reactContext);
42
-    this.reactContext = reactContext;
43
-    mPermissionsModule = new PermissionsModule(this.reactContext);
44
-    mNotificationManagerCompat = NotificationManagerCompat.from(this.reactContext);
45
-  }
46
-
47
-  @Override
48
-  public String getName() {
49
-    return "ReactNativePermissions";
50
-  }
51
-
52
-  @ReactMethod
53
-  public void getPermissionStatus(String permissionString, String nullForiOSCompat, Promise promise) {
54
-    String permission = permissionForString(permissionString);
55
-
56
-    // check if permission is valid
57
-    if (permission == null) {
58
-      promise.reject("unknown-permission", "ReactNativePermissions: unknown permission type - " + permissionString);
59
-      return;
60
-    }
61
-
62
-    if(permission.equals("notification")) {
63
-      if (mNotificationManagerCompat.areNotificationsEnabled()) {
64
-        promise.resolve("authorized");
65
-      } else {
66
-        promise.resolve("denied");
67
-      }
68
-      return;
69
-    }
70
-
71
-    int result = PermissionChecker.checkSelfPermission(this.reactContext, permission);
72
-    switch (result) {
73
-      case PermissionChecker.PERMISSION_DENIED:
74
-        // PermissionDenied could also mean that we've never asked for permission yet.
75
-        // Use shouldShowRequestPermissionRationale to determined which on it is.
76
-        if (getCurrentActivity() != null) {
77
-          boolean deniedOnce = ActivityCompat.shouldShowRequestPermissionRationale(getCurrentActivity(), permission);
78
-          promise.resolve(deniedOnce ? "denied" : "undetermined");
79
-        } else {
80
-          promise.resolve("denied");
81
-        }
82
-        break;
83
-      case PermissionChecker.PERMISSION_DENIED_APP_OP:
84
-        promise.resolve("denied");
85
-        break;
86
-      case PermissionChecker.PERMISSION_GRANTED:
87
-        promise.resolve("authorized");
88
-        break;
89
-      default:
90
-        promise.resolve("undetermined");
91
-        break;
92
-    }
93
-  }
94
-
95
-  @ReactMethod
96
-  public void requestPermission(final String permissionString, String nullForiOSCompat, final Promise promise) {
97
-    String permission = permissionForString(permissionString);
98
-    Callback resolve = new Callback() {
99
-      @Override
100
-      public void invoke(Object... args) {
101
-        getPermissionStatus(permissionString, "", promise);
102
-      }
103
-    };
104
-    Callback reject = new Callback() {
105
-      @Override
106
-      public void invoke(Object... args) {
107
-        // NOOP
108
-      }
109
-    };
110
-
111
-    mPermissionsModule.requestPermission(permission, new PromiseImpl(resolve, reject));
112
-  }
113
-
114
-
115
-  @ReactMethod
116
-  public void canOpenSettings(Promise promise) {
117
-    promise.resolve(true);
118
-  }
119
-
120
-  @ReactMethod
121
-  public void openSettings() {
122
-    final Intent i = new Intent();
123
-    i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
124
-    i.addCategory(Intent.CATEGORY_DEFAULT);
125
-    i.setData(Uri.parse("package:" + this.reactContext.getPackageName()));
126
-    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
127
-    i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
128
-    i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
129
-    this.reactContext.startActivity(i);
130
-  }
131
-
132
-  private String permissionForString(String permission) {
133
-    switch (RNType.valueOf(permission.toUpperCase(Locale.ENGLISH))) {
134
-      case LOCATION:
135
-        return Manifest.permission.ACCESS_FINE_LOCATION;
136
-      case CAMERA:
137
-        return Manifest.permission.CAMERA;
138
-      case MICROPHONE:
139
-        return Manifest.permission.RECORD_AUDIO;
140
-      case CONTACTS:
141
-        return Manifest.permission.READ_CONTACTS;
142
-      case EVENT:
143
-        return Manifest.permission.READ_CALENDAR;
144
-      case STORAGE:
145
-      case PHOTO:
146
-        return Manifest.permission.READ_EXTERNAL_STORAGE;
147
-      case NOTIFICATION:
148
-        return permission;
149
-      default:
150
-        return null;
151
-    }
152
-  }
153
-
154
-}

+ 0
- 28
android/src/main/java/com/joshblour/reactnativepermissions/ReactNativePermissionsPackage.java View File

@@ -1,28 +0,0 @@
1
-package com.joshblour.reactnativepermissions;
2
-
3
-import java.util.Arrays;
4
-import java.util.Collections;
5
-import java.util.List;
6
-
7
-import com.facebook.react.ReactPackage;
8
-import com.facebook.react.bridge.NativeModule;
9
-import com.facebook.react.bridge.ReactApplicationContext;
10
-import com.facebook.react.uimanager.ViewManager;
11
-import com.facebook.react.bridge.JavaScriptModule;
12
-
13
-public class ReactNativePermissionsPackage implements ReactPackage {
14
-    @Override
15
-    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
16
-      return Arrays.<NativeModule>asList(new ReactNativePermissionsModule(reactContext));
17
-    }
18
-
19
-    @Override
20
-    public List<Class<? extends JavaScriptModule>> createJSModules() {
21
-      return Collections.emptyList();
22
-    }
23
-
24
-    @Override
25
-    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
26
-      return Collections.emptyList();
27
-    }
28
-}

+ 85
- 0
index.android.js View File

@@ -0,0 +1,85 @@
1
+'use strict';
2
+
3
+const ReactNative = require('react-native')
4
+const RNPermissions = ReactNative.PermissionsAndroid;
5
+const AsyncStorage = ReactNative.AsyncStorage
6
+
7
+const RNPTypes = {
8
+	location: RNPermissions.PERMISSIONS.ACCESS_FINE_LOCATION,
9
+	camera: RNPermissions.PERMISSIONS.CAMERA,
10
+	microphone: RNPermissions.PERMISSIONS.RECORD_AUDIO,
11
+	contacts: RNPermissions.PERMISSIONS.READ_CONTACTS,
12
+	event: RNPermissions.PERMISSIONS.READ_CALENDAR,
13
+	storage: RNPermissions.PERMISSIONS.READ_EXTERNAL_STORAGE,
14
+	photo: RNPermissions.PERMISSIONS.READ_EXTERNAL_STORAGE,
15
+}
16
+
17
+const RESULTS = {
18
+	[ RNPermissions.RESULTS.GRANTED ]: 'authorized',
19
+	[ RNPermissions.RESULTS.DENIED ]: 'denied',
20
+	[ RNPermissions.RESULTS.NEVER_ASK_AGAIN ]: 'restricted',
21
+}
22
+
23
+const STORAGE_KEY = '@RNPermissions:didAskPermission:'
24
+
25
+const setDidAskOnce = p => AsyncStorage.setItem(STORAGE_KEY + p, 'true')
26
+const getDidAskOnce = p =>  AsyncStorage.getItem(STORAGE_KEY + p).then(res => !!res)
27
+
28
+class ReactNativePermissions {
29
+	canOpenSettings() {
30
+		return false
31
+	}
32
+
33
+	openSettings() {
34
+		return Promise.reject('\'openSettings\' is Depricated on android')
35
+	}
36
+
37
+	getTypes() {
38
+		return Object.keys(RNPTypes);
39
+	}
40
+
41
+	check(permission) {
42
+		const androidPermission = RNPTypes[permission]
43
+  	if (!androidPermission) return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on Android`);
44
+		
45
+		const shouldShowRationale = ReactNative.NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale;
46
+
47
+		return RNPermissions.check(androidPermission)
48
+			.then(isAuthorized => {
49
+				if (isAuthorized) return 'authorized'
50
+
51
+				return getDidAskOnce(permission)
52
+					.then(didAsk => {
53
+						if (didAsk) {
54
+							return shouldShowRationale(androidPermission)
55
+								.then(shouldShow => shouldShow ? 'denied' : 'restricted')
56
+						}
57
+						return 'undetermined'
58
+					})
59
+			})
60
+	}
61
+
62
+
63
+	request(permission) {
64
+		const androidPermission = RNPTypes[permission]
65
+  	if (!androidPermission) return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on Android`);
66
+
67
+
68
+		return RNPermissions.request(androidPermission)
69
+			.then(res => {
70
+				return setDidAskOnce(permission)
71
+					.then(() => RESULTS[res])
72
+			});
73
+	}
74
+
75
+	checkMultiple(permissions) {
76
+		return Promise.all(permissions.map(this.check.bind(this)))
77
+			.then(res => res.reduce((pre, cur, i) => {
78
+				var name = permissions[i]
79
+				pre[name] = cur
80
+				return pre
81
+			}, {}))
82
+	}
83
+}
84
+
85
+module.exports = new ReactNativePermissions()

+ 70
- 0
index.ios.js View File

@@ -0,0 +1,70 @@
1
+'use strict';
2
+
3
+const ReactNative = require('react-native');
4
+const RNPermissions = ReactNative.NativeModules.ReactNativePermissions;
5
+
6
+const RNPTypes = [
7
+	'location',
8
+	'camera',
9
+	'microphone',
10
+	'photo',
11
+	'contacts',
12
+	'event',
13
+	'reminder',
14
+	'bluetooth',
15
+	'notification',
16
+	'backgroundRefresh',
17
+	'speechRecognition',
18
+]
19
+
20
+const DEFAULTS = {
21
+	'location' : 'whenInUse',
22
+	'notification': ['alert', 'badge', 'sound'],
23
+}
24
+
25
+class ReactNativePermissions {
26
+	canOpenSettings() {
27
+		return RNPermissions.canOpenSettings()
28
+	}
29
+
30
+	openSettings() {
31
+		return RNPermissions.openSettings()
32
+	}
33
+
34
+	getTypes() {
35
+		return RNPTypes;
36
+	}
37
+
38
+	check(permission, type) {
39
+  	if (!RNPTypes.includes(permission)) {
40
+			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on iOS`);
41
+		}
42
+		
43
+		return RNPermissions.getPermissionStatus(permission, type);
44
+	}
45
+
46
+	request(permission, type) {
47
+		if (!RNPTypes.includes(permission)) {
48
+			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on iOS`);
49
+		}
50
+
51
+		if (permission == 'backgroundRefresh') {
52
+			return Promise.reject('ReactNativePermissions: You cannot request backgroundRefresh')
53
+		}
54
+
55
+		type = type || DEFAULTS[permission]
56
+
57
+		return RNPermissions.requestPermission(permission, type)
58
+	}
59
+
60
+	checkMultiple(permissions) {
61
+		return Promise.all(permissions.map(this.check.bind(this)))
62
+			.then(res => res.reduce((pre, cur, i) => {
63
+				var name = permissions[i]
64
+				pre[name] = cur
65
+				return pre
66
+			}, {}))
67
+	}
68
+}
69
+
70
+module.exports = new ReactNativePermissions()

+ 7
- 3
package.json View File

@@ -1,13 +1,17 @@
1 1
 {
2 2
   "name": "react-native-permissions",
3
-  "version": "0.3.0",
3
+  "version": "1.0.0",
4 4
   "repository": {
5 5
     "type": "git",
6 6
     "url": "https://github.com/joshblour/react-native-permissions.git"
7 7
   },
8
+  "main": "index",
8 9
   "license": "MIT",
9
-  "keywords": ["react-native", "react-permissions", "permissions" ],
10
-  "main": "ReactNativePermissions",
10
+  "keywords": [
11
+    "react-native",
12
+    "react-permissions",
13
+    "permissions"
14
+  ],
11 15
   "author": "Yonah Forst <yonaforst@hotmail.com>",
12 16
   "homepage": "https://github.com/joshblour/react-native-permissions",
13 17
   "description": "Check user permissions in React Native"