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