我正在使用 typescript 和 expo 为 android 构建一个反应本机应用程序。我想访问相机。为此,我使用了博览会文档中的代码:
import { CameraView, CameraType, useCameraPermissions } from 'expo-camera';
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default function App() {
const [facing, setFacing] = useState<CameraType>('back');
const [permission, requestPermission] = useCameraPermissions();
if (!permission) {
// Camera permissions are still loading.
return <View />;
}
if (!permission.granted) {
// Camera permissions are not granted yet.
return (
<View style={styles.container}>
<Text style={styles.message}>We need your permission to show the camera</Text>
<Button onPress={requestPermission} title="grant permission" />
</View>
);
}
function toggleCameraFacing() {
setFacing(current => (current === 'back' ? 'front' : 'back'));
}
return (
<View style={styles.container}>
<CameraView style={styles.camera} facing={facing}>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={toggleCameraFacing}>
<Text style={styles.text}>Flip Camera</Text>
</TouchableOpacity>
</View>
</CameraView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
message: {
textAlign: 'center',
paddingBottom: 10,
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'transparent',
margin: 64,
},
button: {
flex: 1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
},
});
当我运行时,我收到此错误:
Logs for your project will appear below. Press Ctrl+C to exit.
Android Bundled 52499ms D:\practice_codes\react-native\expo-docu\purnendu-prabhat\node_modules\expo-router\entry.js (1155 modules)
WARN [Reanimated] Reduced motion setting is enabled on this device. This warning is visible only in the development mode. Some animations will be disabled by default. You can override the behavior for individual animations, see https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#reduced-motion-setting-is-enabled-on-this-device.
at ContextNavigator (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:146208:24)
at ExpoRoot (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:146164:28)
at App
at ErrorToastContainer (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:189391:24)
at ErrorOverlay
at withDevTools(ErrorOverlay) (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:189110:27)
at RCTView
at View (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:41374:43)
at RCTView
at View (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:41374:43)
at AppContainer (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:41217:25)
at main(RootComponent) (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:120269:28)
ERROR Error: Cannot find native module 'ExpoCamera', js engine: hermes
at ContextNavigator (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:146208:24)
at ExpoRoot (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:146164:28)
at App
at ErrorToastContainer (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:189391:24)
at ErrorOverlay
at withDevTools(ErrorOverlay) (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:189110:27)
at RCTView
at View (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:41374:43)
at RCTView
at View (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:41374:43)
at AppContainer (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:41217:25)
at main(RootComponent) (http://192.168.1.11:8081/node_modules/expo-router/entry.bundle//&platform=android&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=true&transform.routerRoot=app:120269:28)
我期待顺利运行并能够从移动相机捕获图像。我已经尝试将expo升级到版本51。仍然不起作用。
mode
<CameraView style={styles.camera} ref={cameraRef} mode="video">
或 mode="picture"
import { CameraView, useCameraPermissions } from "expo-camera";
import * as MediaLibrary from "expo-media-library";
import { useState, useRef, Children } from "react";
import {
Button,
StyleSheet,
Text,
TouchableOpacity,
View,
Image,
} from "react-native";
export default function CameraComponent() {
const [permission, requestPermission] = useCameraPermissions();
const [mediaLibraryPermission, requestMediaLibraryPermission] =
MediaLibrary.usePermissions();
const cameraRef = useRef<CameraView>(null);
const [recording, setRecording] = useState(false);
if (!permission) {
// Camera permissions are still loading.
return <View />;
}
const takeVideo = async () => {
console.log("taking video");
if (cameraRef.current) {
try {
setRecording(true);
const video = await cameraRef.current.recordAsync();
console.log("video", video);
if (video) {
console.log("video.uri", video.uri);
const asset = await MediaLibrary.createAssetAsync(video.uri);
console.log(asset);
}
} catch (error) {
console.log("error", error);
}
}
};
const stopVideo = async () => {
if (cameraRef.current) {
try {
const stoppingVideo = await cameraRef.current.stopRecording();
console.log("stopping video", stoppingVideo);
setRecording(false);
} catch (error) {
console.log("error", error);
}
}
};
if (!permission.granted || !mediaLibraryPermission?.granted) {
return (
<View style={styles.container}>
<Text style={{ textAlign: "center" }}>
We need your permission to show the camera
</Text>
<Button onPress={requestPermission} title="grant permission" />
<Button onPress={requestPermission} title="Grant Camera Permission" />
<Button
onPress={requestMediaLibraryPermission}
title="Grant Media Library Permission"
/>
</View>
);
}
return (
<View style={styles.container}>
<CameraView style={styles.camera} ref={cameraRef} mode="picture">
<View className="h-full flex-row items-end justify-center">
<TouchableOpacity
className="bg-red-500 p-4 rounded-lg m-2 "
onPress={takeVideo}
disabled={recording}
>
<Text className="text-white text-center text-2xl font-bold">
{recording ? "Recording" : "Record"}
</Text>
</TouchableOpacity>
<TouchableOpacity
className="bg-red-500 p-4 rounded-lg m-2 "
onPress={stopVideo}
>
<Text className="text-white text-center text-2xl font-bold">
Stop
</Text>
</TouchableOpacity>
</View>
</CameraView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
},
camera: {
flex: 1,
},
button: {
flex: 1,
alignSelf: "flex-end",
alignItems: "center",
},
text: {
fontSize: 24,
fontWeight: "bold",
color: "white",
},
});
我在
"expo": "~51.0.14",
"expo-camera": "~15.0.14",