Created
June 7, 2017 14:33
-
-
Save pvanliefland/8c2522a27daf4759b015e3345ba47dda to your computer and use it in GitHub Desktop.
react-native-camera (workarounds)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import {Platform, PermissionsAndroid, View} from 'react-native'; | |
import RNCamera from 'react-native-camera'; | |
/** | |
* Overridden Camera module | |
* | |
* 3 goals: | |
* - handle Android permissions (https://github.com/lwansbrough/react-native-camera/issues/224 as well as | |
* https://github.com/lwansbrough/react-native-camera/issues/671) | |
* - fix https://github.com/lwansbrough/react-native-camera/issues/604 | |
* - add a "onPermissions" callback informing the parent element of permissions state | |
* | |
* Additional props: | |
* - onPermissions: called with true or false | |
*/ | |
export default class Camera extends RNCamera { | |
// react-native-camera does not handle the new Android permissions system, so we overrides the static checkXYZ() | |
// functions (see implementation below) | |
static checkDeviceAuthorizationStatus = Platform.OS === 'ios' ? | |
RNCamera.checkDeviceAuthorizationStatus : | |
checkDeviceAuthorizationStatusAndroid; | |
static checkVideoAuthorizationStatus = Platform.OS === 'ios' ? | |
RNCamera.checkVideoAuthorizationStatus : | |
checkVideoAuthorizationStatusAndroid; | |
static checkAudioAuthorizationStatus = Platform.OS === 'ios' ? | |
RNCamera.checkAudioAuthorizationStatus : | |
checkAudioAuthorizationStatusAndroid; | |
/** | |
* Overrides react-native camera Camera.componentWillMount | |
* | |
*/ | |
async componentWillMount() { | |
this._addOnBarCodeReadListener(); | |
const captureMode = typeof this.props.captureMode === 'string' ? | |
RNCamera.constants.CaptureMode[this.props.captureMode] : | |
this.props.captureMode; | |
const hasVideoAndAudio = this.props.captureAudio && captureMode === RNCamera.constants.CaptureMode.video; | |
const check = hasVideoAndAudio ? Camera.checkDeviceAuthorizationStatus : Camera.checkVideoAuthorizationStatus; | |
if (check) { | |
const isAuthorized = await check(); | |
if (isAuthorized) { | |
this.props.onPermissions(true); | |
this.setState({isAuthorized}); | |
} | |
else if (Platform.OS === 'android') { | |
const permissionSet = hasVideoAndAudio ? | |
[PermissionsAndroid.PERMISSIONS.CAMERA, PermissionsAndroid.PERMISSIONS.RECORD_AUDIO] : | |
[PermissionsAndroid.PERMISSIONS.CAMERA]; | |
PermissionsAndroid | |
.requestMultiple(permissionSet) | |
.then(results => { | |
const denied = Object.values(results).some(value => value !== 'granted'); | |
this.setState({isAuthorized: !denied}); | |
this.props.onPermissions(!denied); | |
}) | |
.done(); | |
} | |
else { // iOS | |
this.props.onPermissions(false); | |
this.setState({isAuthorized}); | |
} | |
} | |
} | |
/** | |
* Override render - we want to avoid rendering the component itself before getting permissions info for 2 reasons: | |
* - https://github.com/lwansbrough/react-native-camera/issues/604 | |
* - on Android, if directly rendering the component, it doesn't get refreshed just after granting the permissions | |
* | |
* @returns {XML} | |
*/ | |
render() { | |
return this.state.isAuthorized ? super.render() : <View style={this.props.style}/> | |
} | |
} | |
Camera.propTypes = { | |
...RNCamera.propTypes, ...{ | |
onPermissions: React.PropTypes.func | |
} | |
}; | |
Camera.defaultProps = { | |
...RNCamera.defaultProps, ...{ | |
onPermissions: () => { | |
} | |
} | |
}; | |
function checkAuthorizationStatusAndroid(permissionSet) { | |
const androidPermissionPromises = permissionSet.map(PermissionsAndroid.check); | |
return new Promise((resolve, reject) => { | |
Promise | |
.all(androidPermissionPromises) | |
.then(results => { | |
resolve(results.indexOf(false) === -1); | |
}) | |
.catch(reject) | |
.done(); | |
}); | |
} | |
function checkDeviceAuthorizationStatusAndroid() { | |
return checkAuthorizationStatusAndroid([ | |
PermissionsAndroid.PERMISSIONS.CAMERA, PermissionsAndroid.PERMISSIONS.RECORD_AUDIO | |
]); | |
} | |
function checkVideoAuthorizationStatusAndroid() { | |
return checkAuthorizationStatusAndroid([PermissionsAndroid.PERMISSIONS.CAMERA]); | |
} | |
function checkAudioAuthorizationStatusAndroid() { | |
return checkAuthorizationStatusAndroid([PermissionsAndroid.PERMISSIONS.RECORD_AUDIO]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment