Предоставление разрешений в React Native

У меня есть проект, который использует библиотеку React Native Camera, а также CameraRoll из vanilla React Native. Когда я открываю приложение, приложение запрашивает разрешения камеры, но я не знаю, почему. Это только потому, что я указал это в своем 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 Permissions.

Я спрашиваю об этом, потому что хочу запросить эти разрешения сразу, когда пользователь открывает приложение, и это сложно реализовать, поскольку я не знаю, где запрашиваются разрешения. Сейчас пользователь получает запросы на камеру «по умолчанию», но не на хранилище. Почему это?

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>
    )
  }
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
4 623
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это потому, что вы вызываете реакцию на собственную камеру в методе рендеринга:

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

Чтобы решить эту проблему, я использовал тернарный оператор и состояние:

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.info('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>
    );
  }
}

Также для хранения вам не нужно запрашивать разрешения, вам просто нужно написать разрешения на хранение в XML-файле Android. Собственная камера React и Camera Roll запрашивают разрешение по-разному, потому что они сделали библиотеку только такой. Если вы хотите запросить все разрешения одновременно в начале, вы можете использовать собственные разрешения и получить все разрешения, которые вы хотите в начале (возможно, в компоненте заставки, если он у вас есть). Затем, когда вы позже будете использовать реагирующую нативную камеру, она больше не будет запрашивать разрешения.

Другие вопросы по теме

Похожие вопросы

JavaScript для сравнения двух элементов <div> с одинаковым идентификатором и стилизации их, если их содержимое отличается
Haskell Webviewhs getElementById с веб-страницы
Как сделать шкалу времени оси X с равным интервалом между элементами на графике независимо от временного диапазона
$parse:lexerr возникает при создании html-элемента, содержащего ng-click и ссылку String в качестве параметра
Добавить класс в div при прокрутке вверх и вниз
Создать действие с полезной нагрузкой
Есть ли более чистый способ перезапустить вызов API, чем использовать window.setInterval(), чем я делаю здесь?
Как я могу сделать так, чтобы мой оператор подтверждения публиковал статус, если моя функция оценивается как истина, или отменяется, если она ложна?
Как воссоздать эту фоновую кнопку со значком постепенного появления/всплывающего эффекта?
Как анимировать предложение с помощью аниме js вместо анимации css?