在React Native中授予权限

时间:2019-04-26 14:30:38

标签: javascript android react-native react-native-android react-native-camera

我有一个使用React Native Camera库以及香草React Native的CameraRoll的项目。当我打开应用程序时,该应用程序会请求“相机”权限,但我不知道为什么。这仅是因为我在AndroidManifest.xml中指定了吗?

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.gradualcamera">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>


为什么使用React Native Camera时不需要请求权限,但是当我使用CameraRoll时,默认情况下不授予权限,因此我必须使用React Native权限库。

我之所以这样问,是因为我想在用户打开应用程序时立即请求所有这些权限,并且由于不知道在何处请求权限而很难实现。现在,用户“默认”收到了对Camera的请求,但没有收到Storage的请求。为什么会这样?

import React, {Component} from 'react';
import {StyleSheet, View} from 'react-native'
import { RNCamera } from 'react-native-camera'
import { CameraRoll } from 'react-native'
import Permissions from 'react-native-permissions'
import ActionButton from 'react-native-action-button'
import Icon from 'react-native-vector-icons/Ionicons'

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },

  button: {
    height: 200,

    justifyContent: 'flex-end',
    alignItems: 'center'
  },

  actionButtonIcon: {
    fontSize: 20,
    height: 22,
    color: 'white',
  },

});


export default class Cam extends Component {
  constructor() {
    super()
    this.takePicture = this.takePicture.bind(this)

  }

  takePicture = async function() {
    if (this.camera) {
      const options = { quality: 0.5, base64: true }
      const data = await this.camera.takePictureAsync(options)
      CameraRoll.saveToCameraRoll(data.uri)
    }
  }

  render() {
    return (
      <View style={styles.container}>

        <RNCamera
          ref={ref => {this.camera = ref}}
          style={{
            flex: 1,
            width: '100%',
            position: 'relative'
          }}
        >
        </RNCamera>

        <ActionButton size={80} useNativeFeedback={false} buttonColor="rgba(231,76,60,1)">
          <ActionButton.Item useNativeFeedback={false} buttonColor='#9b59b6' title="Settings" onPress={this.props.switchScreen}>
            <Icon name="md-create" style={styles.actionButtonIcon} />
          </ActionButton.Item>
          <ActionButton.Item useNativeFeedback={false} buttonColor='#1abc9c' title="Start" onPress={this.takePicture}>
            <Icon name="md-done-all" style={styles.actionButtonIcon} />
          </ActionButton.Item>

        </ActionButton>

      </View>
    )
  }
}

1 个答案:

答案 0 :(得分:1)

这是因为您要在render方法中调用react native camera:

        <RNCamera
          ref={ref => {this.camera = ref}}
          style={{
            flex: 1,
            width: '100%',
            position: 'relative'
          }}
        >
        </RNCamera>

为了解决这个问题,我使用了三元运算符和state:

import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { RNCamera } from 'react-native-camera';
import { CameraRoll } from 'react-native';
import Permissions from 'react-native-permissions';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/Ionicons';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },

  button: {
    height: 200,

    justifyContent: 'flex-end',
    alignItems: 'center'
  },

  actionButtonIcon: {
    fontSize: 20,
    height: 22,
    color: 'white'
  }
});

export default class Cam extends Component {
  constructor(props) {
    super(props);
    this.state = {
      takePicture: false
    };
  }

  takePicture = async () => {
    console.log('function was called');
    await this.setState({ takePicture: true });
    // if (this.camera) {
    //   const options = { quality: 0.5, base64: true };
    //   const data = await this.camera.takePictureAsync(options);
    //   CameraRoll.saveToCameraRoll(data.uri);
    // }
  };

  render() {
    return (
      <View style={styles.container}>
        {this.state.takePicture ? (
          <RNCamera
            ref={ref => {
              this.camera = ref;
            }}
            style={{
              flex: 1,
              width: '100%',
              position: 'relative'
            }}
          />
        ) : null}

        <ActionButton size={80} useNativeFeedback={false} buttonColor="rgba(231,76,60,1)">
          <ActionButton.Item useNativeFeedback={false} buttonColor="#9b59b6" title="Settings">
            <Icon name="md-create" style={styles.actionButtonIcon} />
          </ActionButton.Item>
          <ActionButton.Item useNativeFeedback={false} buttonColor="#1abc9c" title="Start" onPress={this.takePicture}>
            <Icon name="md-done-all" style={styles.actionButtonIcon} />
          </ActionButton.Item>
        </ActionButton>
      </View>
    );
  }
}

对于存储,您也不需要询问权限,只需要在Android xml文件中写入存储权限即可。 React本机相机和Camera roll要求许可的不同之处在于,它们只是使库成为那样。如果要在开始时同时询问所有权限,则可以使用react本机权限并在开始时获得所需的所有权限(如果有的话,可以在闪屏组件中)。然后,当您稍后使用React Native相机时,它将不会再次请求权限。

相关问题