feat: Install react-native-vision-camera module and handle media permissions
Showing
7 changed files
with
54 additions
and
97 deletions
... | @@ -9,110 +9,39 @@ | ... | @@ -9,110 +9,39 @@ |
9 | */ | 9 | */ |
10 | 10 | ||
11 | import {NativeBaseProvider} from 'native-base'; | 11 | import {NativeBaseProvider} from 'native-base'; |
12 | -import React from 'react'; | 12 | +import React, {useLayoutEffect} from 'react'; |
13 | -import { | 13 | +import {SafeAreaView} from 'react-native'; |
14 | - SafeAreaView, | 14 | +import {Camera, useCameraDevices} from 'react-native-vision-camera'; |
15 | - ScrollView, | ||
16 | - StatusBar, | ||
17 | - StyleSheet, | ||
18 | - Text, | ||
19 | - useColorScheme, | ||
20 | - View, | ||
21 | -} from 'react-native'; | ||
22 | - | ||
23 | -import { | ||
24 | - Colors, | ||
25 | - DebugInstructions, | ||
26 | - Header, | ||
27 | - LearnMoreLinks, | ||
28 | - ReloadInstructions, | ||
29 | -} from 'react-native/Libraries/NewAppScreen'; | ||
30 | - | ||
31 | -const Section: React.FC<{ | ||
32 | - title: string; | ||
33 | -}> = ({children, title}) => { | ||
34 | - const isDarkMode = useColorScheme() === 'dark'; | ||
35 | - return ( | ||
36 | - <View style={styles.sectionContainer}> | ||
37 | - <Text | ||
38 | - style={[ | ||
39 | - styles.sectionTitle, | ||
40 | - { | ||
41 | - color: isDarkMode ? Colors.white : Colors.black, | ||
42 | - }, | ||
43 | - ]}> | ||
44 | - {title} | ||
45 | - </Text> | ||
46 | - <Text | ||
47 | - style={[ | ||
48 | - styles.sectionDescription, | ||
49 | - { | ||
50 | - color: isDarkMode ? Colors.light : Colors.dark, | ||
51 | - }, | ||
52 | - ]}> | ||
53 | - {children} | ||
54 | - </Text> | ||
55 | - </View> | ||
56 | - ); | ||
57 | -}; | ||
58 | 15 | ||
59 | const App = () => { | 16 | const App = () => { |
60 | - const isDarkMode = useColorScheme() === 'dark'; | 17 | + const devices = useCameraDevices(); |
61 | - | 18 | + const device = devices.front; |
62 | - const backgroundStyle = { | 19 | + |
63 | - backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, | 20 | + useLayoutEffect(() => { |
64 | - }; | 21 | + (async () => { |
22 | + const [cameraPermission, micPermission] = await Promise.all([ | ||
23 | + Camera.getCameraPermissionStatus(), | ||
24 | + Camera.getMicrophonePermissionStatus(), | ||
25 | + ]); | ||
26 | + | ||
27 | + const requests: (() => Promise<unknown>)[] = []; | ||
28 | + if (cameraPermission !== 'authorized') { | ||
29 | + requests.push(Camera.requestCameraPermission); | ||
30 | + } | ||
31 | + if (micPermission !== 'authorized') { | ||
32 | + requests.push(Camera.requestMicrophonePermission); | ||
33 | + } | ||
34 | + await Promise.all(requests.map(request => request())); | ||
35 | + })(); | ||
36 | + }, []); | ||
65 | 37 | ||
66 | return ( | 38 | return ( |
67 | <NativeBaseProvider> | 39 | <NativeBaseProvider> |
68 | - <SafeAreaView style={backgroundStyle}> | 40 | + <SafeAreaView> |
69 | - <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> | 41 | + {device && <Camera isActive device={device} />} |
70 | - <ScrollView | ||
71 | - contentInsetAdjustmentBehavior="automatic" | ||
72 | - style={backgroundStyle}> | ||
73 | - <Header /> | ||
74 | - <View | ||
75 | - style={{ | ||
76 | - backgroundColor: isDarkMode ? Colors.black : Colors.white, | ||
77 | - }}> | ||
78 | - <Section title="Step One"> | ||
79 | - Edit <Text style={styles.highlight}>App.tsx</Text> to change this | ||
80 | - screen and then come back to see your edits. | ||
81 | - </Section> | ||
82 | - <Section title="See Your Changes"> | ||
83 | - <ReloadInstructions /> | ||
84 | - </Section> | ||
85 | - <Section title="Debug"> | ||
86 | - <DebugInstructions /> | ||
87 | - </Section> | ||
88 | - <Section title="Learn More"> | ||
89 | - Read the docs to discover what to do next: | ||
90 | - </Section> | ||
91 | - <LearnMoreLinks /> | ||
92 | - </View> | ||
93 | - </ScrollView> | ||
94 | </SafeAreaView> | 42 | </SafeAreaView> |
95 | </NativeBaseProvider> | 43 | </NativeBaseProvider> |
96 | ); | 44 | ); |
97 | }; | 45 | }; |
98 | 46 | ||
99 | -const styles = StyleSheet.create({ | ||
100 | - sectionContainer: { | ||
101 | - marginTop: 32, | ||
102 | - paddingHorizontal: 24, | ||
103 | - }, | ||
104 | - sectionTitle: { | ||
105 | - fontSize: 24, | ||
106 | - fontWeight: '600', | ||
107 | - }, | ||
108 | - sectionDescription: { | ||
109 | - marginTop: 8, | ||
110 | - fontSize: 18, | ||
111 | - fontWeight: '400', | ||
112 | - }, | ||
113 | - highlight: { | ||
114 | - fontWeight: '700', | ||
115 | - }, | ||
116 | -}); | ||
117 | - | ||
118 | export default App; | 47 | export default App; | ... | ... |
... | @@ -2,6 +2,8 @@ | ... | @@ -2,6 +2,8 @@ |
2 | package="com.detectapp"> | 2 | package="com.detectapp"> |
3 | 3 | ||
4 | <uses-permission android:name="android.permission.INTERNET" /> | 4 | <uses-permission android:name="android.permission.INTERNET" /> |
5 | + <uses-permission android:name="android.permission.CAMERA" /> | ||
6 | + <uses-permission android:name="android.permission.RECORD_AUDIO" /> | ||
5 | 7 | ||
6 | <application | 8 | <application |
7 | android:name=".MainApplication" | 9 | android:name=".MainApplication" | ... | ... |
... | @@ -37,6 +37,10 @@ | ... | @@ -37,6 +37,10 @@ |
37 | </dict> | 37 | </dict> |
38 | <key>NSLocationWhenInUseUsageDescription</key> | 38 | <key>NSLocationWhenInUseUsageDescription</key> |
39 | <string></string> | 39 | <string></string> |
40 | + <key>NSCameraUsageDescription</key> | ||
41 | + <string>$(PRODUCT_NAME) needs access to your Camera.</string> | ||
42 | + <key>NSMicrophoneUsageDescription</key> | ||
43 | + <string>$(PRODUCT_NAME) needs access to your Microphone.</string> | ||
40 | <key>UILaunchStoryboardName</key> | 44 | <key>UILaunchStoryboardName</key> |
41 | <string>LaunchScreen</string> | 45 | <string>LaunchScreen</string> |
42 | <key>UIRequiredDeviceCapabilities</key> | 46 | <key>UIRequiredDeviceCapabilities</key> | ... | ... |
... | @@ -356,6 +356,10 @@ PODS: | ... | @@ -356,6 +356,10 @@ PODS: |
356 | - RNSVG (12.3.0): | 356 | - RNSVG (12.3.0): |
357 | - React-Core | 357 | - React-Core |
358 | - SocketRocket (0.6.0) | 358 | - SocketRocket (0.6.0) |
359 | + - VisionCamera (2.13.3): | ||
360 | + - React | ||
361 | + - React-callinvoker | ||
362 | + - React-Core | ||
359 | - Yoga (1.14.0) | 363 | - Yoga (1.14.0) |
360 | - YogaKit (1.18.1): | 364 | - YogaKit (1.18.1): |
361 | - Yoga (~> 1.14) | 365 | - Yoga (~> 1.14) |
... | @@ -417,6 +421,7 @@ DEPENDENCIES: | ... | @@ -417,6 +421,7 @@ DEPENDENCIES: |
417 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) | 421 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) |
418 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) | 422 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) |
419 | - RNSVG (from `../node_modules/react-native-svg`) | 423 | - RNSVG (from `../node_modules/react-native-svg`) |
424 | + - VisionCamera (from `../node_modules/react-native-vision-camera`) | ||
420 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) | 425 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) |
421 | 426 | ||
422 | SPEC REPOS: | 427 | SPEC REPOS: |
... | @@ -502,6 +507,8 @@ EXTERNAL SOURCES: | ... | @@ -502,6 +507,8 @@ EXTERNAL SOURCES: |
502 | :path: "../node_modules/react-native/ReactCommon" | 507 | :path: "../node_modules/react-native/ReactCommon" |
503 | RNSVG: | 508 | RNSVG: |
504 | :path: "../node_modules/react-native-svg" | 509 | :path: "../node_modules/react-native-svg" |
510 | + VisionCamera: | ||
511 | + :path: "../node_modules/react-native-vision-camera" | ||
505 | Yoga: | 512 | Yoga: |
506 | :path: "../node_modules/react-native/ReactCommon/yoga" | 513 | :path: "../node_modules/react-native/ReactCommon/yoga" |
507 | 514 | ||
... | @@ -552,6 +559,7 @@ SPEC CHECKSUMS: | ... | @@ -552,6 +559,7 @@ SPEC CHECKSUMS: |
552 | ReactCommon: bf2888a826ceedf54b99ad1b6182d1bc4a8a3984 | 559 | ReactCommon: bf2888a826ceedf54b99ad1b6182d1bc4a8a3984 |
553 | RNSVG: 302bfc9905bd8122f08966dc2ce2d07b7b52b9f8 | 560 | RNSVG: 302bfc9905bd8122f08966dc2ce2d07b7b52b9f8 |
554 | SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 | 561 | SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 |
562 | + VisionCamera: c1c171fcdbf18c438987847f785829c5638f3a4c | ||
555 | Yoga: 17cd9a50243093b547c1e539c749928dd68152da | 563 | Yoga: 17cd9a50243093b547c1e539c749928dd68152da |
556 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a | 564 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a |
557 | 565 | ... | ... |
... | @@ -14,7 +14,8 @@ | ... | @@ -14,7 +14,8 @@ |
14 | "react": "17.0.2", | 14 | "react": "17.0.2", |
15 | "react-native": "0.68.1", | 15 | "react-native": "0.68.1", |
16 | "react-native-safe-area-context": "^4.2.5", | 16 | "react-native-safe-area-context": "^4.2.5", |
17 | - "react-native-svg": "^12.3.0" | 17 | + "react-native-svg": "^12.3.0", |
18 | + "react-native-vision-camera": "^2.13.3" | ||
18 | }, | 19 | }, |
19 | "devDependencies": { | 20 | "devDependencies": { |
20 | "@babel/core": "^7.12.9", | 21 | "@babel/core": "^7.12.9", | ... | ... |
... | @@ -6706,6 +6706,11 @@ react-native-svg@^12.3.0: | ... | @@ -6706,6 +6706,11 @@ react-native-svg@^12.3.0: |
6706 | css-select "^4.2.1" | 6706 | css-select "^4.2.1" |
6707 | css-tree "^1.0.0-alpha.39" | 6707 | css-tree "^1.0.0-alpha.39" |
6708 | 6708 | ||
6709 | +react-native-vision-camera@^2.13.3: | ||
6710 | + version "2.13.3" | ||
6711 | + resolved "https://registry.yarnpkg.com/react-native-vision-camera/-/react-native-vision-camera-2.13.3.tgz#cacd20b7f3fd777691496f007a47a34c02be93be" | ||
6712 | + integrity sha512-aikp6kNmb9b8lsVFKEKCBgch5h93Cs8Qqw/bSZsn/dO+Qa4uktpe89WIO1VTs88d40vJiLeYFlbyWe589E/UuA== | ||
6713 | + | ||
6709 | react-native@0.68.1: | 6714 | react-native@0.68.1: |
6710 | version "0.68.1" | 6715 | version "0.68.1" |
6711 | resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.68.1.tgz#c3d92f89028cdc2453fe7cd2d532b3f68d1c27c8" | 6716 | resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.68.1.tgz#c3d92f89028cdc2453fe7cd2d532b3f68d1c27c8" | ... | ... |
-
Please register or login to post a comment