123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // @flow
  2. import React from 'react';
  3. import Permissions, {type PermissionStatus} from 'react-native-permissions';
  4. import {
  5. StyleSheet,
  6. TouchableHighlight,
  7. Text,
  8. View,
  9. Alert,
  10. AppState,
  11. Platform,
  12. } from 'react-native';
  13. type State = {
  14. types: string[],
  15. status: {[permission: string]: PermissionStatus},
  16. isAlways: boolean,
  17. };
  18. export default class App extends React.Component<{}, State> {
  19. state: State = {
  20. types: [],
  21. status: {},
  22. isAlways: false,
  23. statuses: {},
  24. };
  25. componentDidMount() {
  26. const types = Permissions.getTypes();
  27. this.setState({types});
  28. this.updatePermissions(types);
  29. AppState.addEventListener('change', this.onAppStateChange);
  30. }
  31. componentWillUnmount() {
  32. AppState.removeEventListener('change', this.onAppStateChange);
  33. }
  34. onAppStateChange = (appState: 'active' | 'inactive' | 'background') => {
  35. if (appState === 'active') {
  36. this.updatePermissions(this.state.types);
  37. }
  38. };
  39. openSettings = () =>
  40. Permissions.canOpenSettings().then(canIt => {
  41. if (canIt) {
  42. return Permissions.openSettings();
  43. }
  44. Alert.alert(
  45. 'Not supported',
  46. 'openSettings is currently not supported on this platform',
  47. );
  48. });
  49. updatePermissions = (types: string[]) => {
  50. Permissions.checkMultiple(types)
  51. .then(status => {
  52. if (this.state.isAlways) {
  53. return Permissions.check('location', 'always').then(location => ({
  54. ...status,
  55. location,
  56. }));
  57. }
  58. return status;
  59. })
  60. .then(status => this.setState({status}));
  61. };
  62. requestPermission = (permission: string) => {
  63. var options;
  64. if (permission == 'location') {
  65. options = this.state.isAlways ? 'always' : 'whenInUse';
  66. }
  67. Permissions.request(permission, options)
  68. .then(result => {
  69. this.setState({status: {...this.state.status, [permission]: result}});
  70. })
  71. .catch(error => console.warn(error));
  72. };
  73. onLocationSwitchChange = () => {
  74. this.setState({isAlways: !this.state.isAlways});
  75. this.updatePermissions(this.state.types);
  76. };
  77. render() {
  78. return (
  79. <View style={styles.container}>
  80. {this.state.types.map(permission => (
  81. <TouchableHighlight
  82. style={[styles.button, styles[this.state.status[permission]]]}
  83. key={permission}
  84. onPress={() => this.requestPermission(permission)}>
  85. <View>
  86. <Text style={styles.text}>
  87. {Platform.OS == 'ios' && permission == 'location'
  88. ? `location ${this.state.isAlways ? 'always' : 'whenInUse'}`
  89. : permission}
  90. </Text>
  91. <Text style={styles.subtext}>
  92. {this.state.status[permission]}
  93. </Text>
  94. </View>
  95. </TouchableHighlight>
  96. ))}
  97. <View style={styles.footer}>
  98. <TouchableHighlight
  99. style={styles['footer_' + Platform.OS]}
  100. onPress={this.onLocationSwitchChange}>
  101. <Text style={styles.text}>Toggle location type</Text>
  102. </TouchableHighlight>
  103. <TouchableHighlight onPress={this.openSettings}>
  104. <Text style={styles.text}>Open settings</Text>
  105. </TouchableHighlight>
  106. </View>
  107. <Text style={styles['footer_' + Platform.OS]}>
  108. Note: microphone permissions may not work on iOS simulator. Also,
  109. toggling permissions from the settings menu may cause the app to
  110. crash. This is normal on iOS. Google "ios crash permission change"
  111. </Text>
  112. </View>
  113. );
  114. }
  115. }
  116. const styles = StyleSheet.create({
  117. container: {
  118. flex: 1,
  119. justifyContent: 'center',
  120. backgroundColor: '#F5FCFF',
  121. padding: 10,
  122. },
  123. text: {
  124. textAlign: 'center',
  125. fontWeight: 'bold',
  126. },
  127. subtext: {
  128. textAlign: 'center',
  129. },
  130. button: {
  131. margin: 5,
  132. borderColor: 'black',
  133. borderWidth: 3,
  134. overflow: 'hidden',
  135. },
  136. buttonInner: {
  137. flexDirection: 'column',
  138. },
  139. undetermined: {
  140. backgroundColor: '#E0E0E0',
  141. },
  142. authorized: {
  143. backgroundColor: '#C5E1A5',
  144. },
  145. denied: {
  146. backgroundColor: '#ef9a9a',
  147. },
  148. restricted: {
  149. backgroundColor: '#ef9a9a',
  150. },
  151. footer: {
  152. padding: 10,
  153. flexDirection: 'row',
  154. justifyContent: 'space-between',
  155. },
  156. footer_android: {
  157. height: 0,
  158. width: 0,
  159. },
  160. });