You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo React Native问题:BarcodeScanner.requestPermissionsAsync()未弹出权限请求弹窗

问题分析与解决方案

嘿,我一眼就发现问题所在了!你能看到ASKING的日志输出,说明askForCameraPermission函数确实被调用了,但里面的权限请求逻辑根本没执行——因为你在函数内部定义了一个异步箭头函数,但从来没调用它!

具体错误点

看这段代码:

const askForCameraPermission = () =>{
  console.log('ASKING')
  async () => {
    const {status} = await BarCodeScanner.requestPermissionsAsync();
    setHasPermission(status === 'granted');
  }
}

这里的async () => {...}只是一个定义好但未执行的函数,相当于你写了一段代码但没告诉程序要运行它,所以权限请求的代码完全没触发,对话框自然不会弹出来。

两种修正方案

方案1:直接把askForCameraPermission改成异步函数

这种方式最简洁,直接让整个函数变成异步的,内部可以正常使用await:

const askForCameraPermission = async () =>{
  console.log('ASKING')
  const {status} = await BarCodeScanner.requestPermissionsAsync();
  setHasPermission(status === 'granted');
}

方案2:立即执行内部的匿名异步函数

如果你不想修改函数的结构(虽然没必要),可以用立即执行函数表达式(IIFE)触发代码:

const askForCameraPermission = () =>{
  console.log('ASKING')
  (async () => {
    const {status} = await BarCodeScanner.requestPermissionsAsync();
    setHasPermission(status === 'granted');
  })(); // 加括号执行定义好的异步函数
}

修正后的完整代码

import React, { useState, useEffect } from 'react';
import { Text,SafeAreaView, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';

const ScannerComponent =()=> {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

  // 修正后的权限请求函数
  const askForCameraPermission = async () =>{
    console.log('ASKING')
    const {status} = await BarCodeScanner.requestPermissionsAsync();
    setHasPermission(status === 'granted');
  }

  useEffect(() => {
    askForCameraPermission();
  }, []);

  const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    alert(`Bar code with type ${type} and data ${data} has been scanned!`);
  };

  if (hasPermission === null) {
    return (<View style={styles.container}><Text style={styles.text}>Requesting for camera permission</Text></View>);
  }
  if (hasPermission === false) {
    return (<View style={styles.container}><Text style={styles.text}>No access to camera</Text></View>);
  }

  return (
    <SafeAreaView style={styles.container}>
      <Text>hello</Text> {/* 修正:Text组件没有value属性,直接传入文本内容 */}
      <View style={styles.scanner}>
        <BarCodeScanner
          onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
          style={StyleSheet.absoluteFillObject}
        />
      </View>
      {scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
    </SafeAreaView>
  );
}

// 补充样式避免报错(原代码未包含)
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  scanner: {
    flex: 1,
    width: '100%',
  },
  text: {
    fontSize: 16,
  }
});

export default ScannerComponent;

另外帮你修正了一个小细节:原代码里的<Text value='hello' />是错误的,Text组件没有value属性,应该直接写成<Text>hello</Text>。

额外排查点

如果修正后还是没弹出权限对话框,可以检查:

  • 确保expo-barcode-scanner依赖已正确安装,Expo项目版本为最新
  • 在app.json/app.config.js中确认已声明相机权限:
{
  "expo": {
    "android": {
      "permissions": ["CAMERA"]
    },
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "需要访问相机来扫描条形码"
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者pikcahu420

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 03:07:31