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

Expo环境下React Native WebView Android端相机权限问题解决

Expo Android 启用WebView相机权限的解决方案

要让WebView能调用相机,需要同时处理原生权限申请和WebView的配置,具体步骤如下:

1. 配置项目权限

首先在项目的app.json(或app.config.js)中声明相机相关权限,让Expo打包时包含这些权限声明:

{
  "expo": {
    "permissions": ["CAMERA", "RECORD_AUDIO"],
    "android": {
      "permissions": ["android.permission.CAMERA", "android.permission.RECORD_AUDIO"]
    }
  }
}

注:如果网页只需要相机不需要麦克风,可以去掉RECORD_AUDIO相关权限。

2. 动态申请用户权限

Android要求必须动态向用户申请敏感权限,所以在组件初始化时请求相机权限:
首先安装依赖(如果未安装):

expo install expo-camera

然后修改你的HealthCheck组件:

import React, { useState, useEffect } from "react";
import { WebView } from "react-native-webview";
import { StyleSheet, Text, ActivityIndicator } from "react-native";
import { Camera } from 'expo-camera';

export default function HealthCheck({ route }) {
  const [hasCameraPermission, setHasCameraPermission] = useState(null);

  useEffect(() => {
    // 动态请求相机权限
    const requestPermissions = async () => {
      const cameraStatus = await Camera.requestCameraPermissionsAsync();
      // 如果需要麦克风,添加以下代码
      // const audioStatus = await Camera.requestMicrophonePermissionsAsync();
      setHasCameraPermission(cameraStatus.status === 'granted');
    };

    requestPermissions();
  }, []);

  // 权限未授权时显示提示
  if (hasCameraPermission === false) {
    return <Text>需要相机权限才能使用此功能</Text>;
  }

  // 权限未加载完成时显示加载状态
  if (hasCameraPermission === null) {
    return <ActivityIndicator />;
  }

  return (
    <WebView
      style={styles.webViewContainer}
      source={{ uri: route.params.url }}
      originWhitelist={["*"]}
      allowsInlineMediaPlayback
      javaScriptEnabled
      scalesPageToFit
      mediaPlaybackRequiresUserAction={false}
      startInLoadingState
      javaScriptEnabledAndroid
      // 开启DOM存储,部分网页依赖此处理权限状态
      domStorageEnabled={true}
      // Android专属配置,允许文件/内容访问,禁用媒体播放手势要求
      androidSettings={{
        allowFileAccess: true,
        allowContentAccess: true,
        mediaPlaybackRequiresUserGesture: false,
      }}
      // 处理WebView的权限请求,关键!
      webChromeClient={{
        onPermissionRequest: (request) => {
          const resources = request.getResources();
          // 判断请求的是相机/麦克风权限,直接授权
          if (resources.includes('android.webkit.resource.CAMERA') || resources.includes('android.webkit.resource.MICROPHONE')) {
            request.grant(resources);
          } else {
            request.deny();
          }
        },
      }}
    />
  );
}

const styles = StyleSheet.create({
  webViewContainer: {
    flex: 1,
  },
});

3. 关键注意点

  • 必须先获取原生相机权限,网页的权限请求才会触发;
  • webChromeClient的onPermissionRequest方法是Android上处理网页权限请求的核心,默认WebView不会自动授权,需要手动处理;
  • 确保domStorageEnabled开启,部分网页会使用本地存储记录权限授权状态;
  • 测试时使用Expo Go或构建独立APK,不要使用模拟器(模拟器可能没有相机硬件支持)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:45:45