About react native vision camera taking picture and save - android

I am new in react native. What do I need to do if I want to have a picture on the desktop after I click on the button? Just simply want to take a picture. I have tried to do so and succeed yesterday but I can't do that now.
function Cam() {
const [hasPermission, setHasPermission] = React.useState(false);
const isFocused = useIsFocused()
const devices = useCameraDevices()
const device = devices.back
const camera = useRef(null)
const takePhotoOptions = {
qualityPrioritization: 'speed',
flash: 'off'
};
React.useEffect(() => {
(async () => {
const status = await Camera.requestCameraPermission();
setHasPermission(status === 'authorized');
})();
}, []);
const takePhoto = async () => {
try {
//Error Handle better
if (camera.current == null) throw new Error('Camera Ref is Null');
console.log('Photo taking ....');
const photo = await camera.current.takePhoto(takePhotoOptions);
console.log(photo.path)
} catch (error) {
console.log(error);
}
};
function renderCamera() {
if (device == null) {
return (
<View>
<Text style={{ color: '#fff' }}>Loading</Text>
</View>
)
}
else {
return (
<View style={{ flex: 1 }}>
{device != null &&
hasPermission && (
<>
<Camera
ref={camera}
style={StyleSheet.absoluteFill}
device={device}
isActive={isFocused}
photo={true}
/>
<Text> Too much code, I delete something here </Text>
</>
)}
</View>
)
}
}
return (
<View style={{ flex: 1 }}>
{renderCamera()}
</View>
);
}
export default Cam;
enter image description here
as you can see here, the frame is not important for now.

You can use react-native-fs
// Create pictureDirectory if it does not exist
await RNFS.mkdir(pictureDirectory);
// Move picture to pictureDirectory
const filename = R.last(data.path.split('/'))!;
await RNFS.moveFile(data.path, `${pictureDirectory}/${filename}`);

import {Camera} from 'react-native-vision-camera';
instead of using const camera = useRef(null) use const camera = useRef<Camera>(null)

Related

Real-time line charting with React-Native

I'm new to drawing a graph with react-native. The problem is, I can read the data sent with Ble as a value on the screen, but I'm having trouble making real-time graphs. There must be a mistake somewhere. I tried many different methods.
The code below is my screen code.
const disconnectDevice = useCallback(async () => {
navigation.goBack();
const isDeviceConnected = await device.isConnected();
if (isDeviceConnected) {
await device.cancelConnection();
navigation.navigate('Home');
}
}, [device, navigation]);
useEffect(() => {
const getDeviceInformations = async () => {
// connect to the device
const connectedDevice = await device.connect();
setIsConnected(true);
// discover all device services and characteristics
const allServicesAndCharacteristics = await connectedDevice.discoverAllServicesAndCharacteristics();
// get the services only
const discoveredServices = await allServicesAndCharacteristics.services();
setServices(discoveredServices);
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Permission Localisation Bluetooth',
message: 'Requirement for Bluetooth',
buttonNeutral: 'Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
}
);
};
getDeviceInformations();
device.onDisconnected(() => {
navigation.navigate('Home');
});
// give a callback to the useEffect to disconnect the device when we will leave the device screen
return () => {
disconnectDevice();
navigation.navigate('Home');
};
}, [device, disconnectDevice, navigation]);
return (
<ScrollView contentContainerStyle={styles.container}>
<TouchableOpacity style={styles.button} onPress={disconnectDevice}>
<Text style={{fontFamily:"SairaExtraCondensed-Thin",textAlign:"center",fontSize:15,color:"white"}}>Antrenmanı Sonlandır</Text>
</TouchableOpacity>
<View>
<View style={styles.header} >
<Text>{`Name : ${device.name}`}</Text>
<Text>{`Is connected : ${isConnected}`}</Text>
</View>
<View>
<>
{services &&
services.map((service) => {
return(
<>
<ServiceCard service={service} />
<LineChart
style={{ height: 200 }}
gridMin={0}
gridMax={300}
data={[service]}
svg={{ stroke: 'rgb(134, 65, 244)' }}
contentInset={{ top: 20, bottom: 20 }}>
</LineChart></>
)
})}
</>
</View>
</View>
<View>
</View>
</ScrollView>
);
};
The service component, where the values ​​were decoded last, is as follows;
type ServiceCardProps = {
service: Service;
};
const ServiceCard = ({ service }: ServiceCardProps) => {
const [descriptors, setDescriptors] = useState<Descriptor[]>([]);
const [characteristics, setCharacteristics] = useState<Characteristic[]>([]);
const [areCharacteristicsVisible, setAreCharacteristicsVisible] = useState(
false,
);
useEffect(() => {
const getCharacteristics = async () => {
const newCharacteristics = await service.characteristics();
setCharacteristics(newCharacteristics);
newCharacteristics.forEach(async (characteristic) => {
const newDescriptors = await characteristic.descriptors();
setDescriptors((prev) => [...new Set([...prev, ...newDescriptors])]);
});
};
getCharacteristics();
}, [service]);
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => {
setAreCharacteristicsVisible((prev) => !prev);
}}>
<Text>{`UUID : ${service.uuid}`}</Text>
</TouchableOpacity>
{areCharacteristicsVisible &&
characteristics &&
characteristics.map((char) => (
<CharacteristicCard key={char.id} char={char} />
))}
{descriptors &&
descriptors.map((descriptor) => (
<DescriptorCard key={descriptor.id} descriptor={descriptor} />
))}
</View>
);
};
Data is being decoded with Ble. Then it is displayed as a value on the screen via the latest service map. I want to see the graph on the screen in real time like in this code. What error could be below?
Nothing appears on the screen. I only see values.
Thanks

react native app having error when run on device

I have implement an barcode scanner app by using react native when I use web to execute the program all the function are work perfectly it can pass the data to api and post to the server but when I try to use it on my android and iOS device it cannot post the data below is my code for scanner.js
import React, { useState, useEffect,Component,onMount} from 'react';
import { Text,TextInput, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import {useNavigation} from'#react-navigation/native';
import {StatusBar} from 'expo-status-bar';
export default function Scanner () {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [userid, setuserid] = useState('Not yet scanned')
const [currentDate, setCurrentDate] = useState('');
const navigation = useNavigation();
const askForCameraPermission = () => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})()
}
// Request Camera Permission
useEffect(() => {
askForCameraPermission();
}, []);
useEffect(() => {
var date = new Date().getDate(); //Current Date
var month = new Date().getMonth() + 1; //Current Month
var year = new Date().getFullYear(); //Current Year
var hours = new Date().getHours(); //Current Hours
var min = new Date().getMinutes(); //Current Minutes
var sec = new Date().getSeconds(); //Current Seconds
setCurrentDate(
date + '/' + month + '/' + year
+ ' ' + hours + ':' + min + ':' + sec
);
}, []);
// What happens when we scan the bar code
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setuserid(data )
};
// Check permissions and return the screens
if (hasPermission === null) {
return (
<View style={styles.container}>
<Text>Requesting for camera permission</Text>
</View>)
}
if (hasPermission === false) {
return (
<View style={styles.container}>
<Text style={{ margin: 10 }}>No access to camera</Text>
<Button title={'Allow Camera'} onPress={() => askForCameraPermission()} />
</View>)
}
const Register = () => {
let InsertAPIURL = "https://localhost/api/insert.php";
let headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'POST, PUT, PATCH, GET, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, X-Api-Key, X-Requested-With, Content-Type, Accept, Authorization',
}
let Data = {
userid:userid,
};
fetch(InsertAPIURL, {
mode:'no-cors',
method: 'POST',
headers: headers,
body: JSON.stringify(Data)
})
try{
((response) =>response.json()),
((response)=>{
alert(response[0].Message);
})
}
catch{
((error) => {
alert("Error"+error);
})
} }
// Return the View
return (
<View style={styles.container}>
<View style={styles.barcodebox}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{ height: 400, width: 400 }} />
</View>
<Text style={styles.maintext}>{userid + '\n'+currentDate}
</Text>
{
scanned && <Button title={'Scan again?'} onPress={() => setScanned(false)} color='tomato' />
}
{
scanned && <Button title={'OK'} onPress={()=> navigation.navigate('Home',{userid},Register())} />
}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
maintext: {
fontSize: 16,
margin: 20,
},
barcodebox: {
alignItems: 'center',
justifyContent: 'center',
height: 300,
width: 300,
overflow: 'hidden',
borderRadius: 30,
backgroundColor: 'tomato'
}
});
I have make a research on other source they said that change the apiurl to http://10.0.2.2 instead of localhost host to made it function on android device but after I tried this method it also cannot solve the issue. this is my first react native project and I really hang on this part a few day already hope u guys help thanks in advance
You need to provide your ip address instead of the localhost, you can find it by doing ifconfig on linux/Mac and ipconfig on windows.
So you have something like this: 192.0.0.1:3000/yoururl instead of localhost:3000/yoururl
This is only needed if you want to test on a real device which is connected to your computer.

Can't access array element in render mode even if it exists

I have React native project with redux state manager, using redux-saga and immer for dealing with immutables. There is a simple screen, where i fetch news, using onFocusEffect(). I get data correctly (debug with flipper and redux debugger plugin), but when i try to access news.news.headerImages[0] my app crashes with ERROR TypeError: Cannot convert undefined value to object.
So, here is the code:
Action creator:
const startLoadNews = (id) => {
return { type: Types.START_LOAD_NEWS, id };
};
Saga:
function* fetchNews(action) {
try {
const news = yield call(FakeApi.getNewsLocal, action.id);
yield put(newsActions.loadNewsSuccess(news));
} catch (error) {
yield put(newsActions.loadNewsError('Cant load news'));
}
}
function* watchNews() {
yield takeLatest(types.START_LOAD_NEWS, fetchNews);
}
export function* newsSaga() {
yield all([watchNews()]);
}
Reducer:
const initialState = {
news: {},
loading: false,
error: '',
};
export const newsReducer = (state = initialState, action) =>
produce(state, draft => {
switch (action.type) {
case types.START_LOAD_NEWS:
draft.loading = true;
draft.error = '';
draft.news = {};
break;
case types.LOAD_NEWS_SUCCESS:
draft.loading = false;
draft.error = '';
draft.news = {...action.news};
break;
case types.LOAD_NEWS_ERROR:
draft.loading = false;
draft.error = action.error;
draft.news = {};
break;
}
});
And my NewsScreen component, connected to store:
export const NewsScreen = (params) => {
const { route, news, loadNews } = params;
const { newsId } = route.params;
useFocusEffect(
useCallback(() => { loadNews(newsId); }, [])
);
const testImg = 'https://img.freepik.com/free-photo/confident-business-team-with-leader_1098-3228.jpg';
return (
news.loading ? (
<Spinner/>
) : (
<View style={styles.container}>
<ScrollView>
{true && (
<TouchableOpacity>
<ImageBackground style={styles.image} source={{uri: news.news.headerImages[0]}}>
<View style={styles.notifyer}>
<Notifyer>1-3</Notifyer>
</View>
</ImageBackground>
</TouchableOpacity>
)}
<View style={styles.content}>
<View style={styles.header}>
<Text style={styles.dimmed}>{jsDateTodmY(news.news.date)} | <Text>{news.news.category} </Text></Text>
</View>
<View style={styles.textArea}>
<Text style={styles.newsText}>{news.news.fullText}</Text>
</View>
<View style={styles.footer}>
<Text style={styles.sourceTitle}>Source</Text>
<Text style={styles.source}>{news.news.source}</Text>
</View>
</View>
</ScrollView>
</View>
)
);
};
So, if i replace news.news.headerImages[0] with testImg it loads good, event if i access to news object below in code. Where i do wrong?
Figured it out:
After first render there is no news.news.headerImages array of my state, so when i try to acccess to undefined.[index] it crashes. Fixed it by adding an array to my initial state:
const initialState = {
news: { headerImages:[] },
loading: false,
error: '',
};

How to open default Contact app in react native using Expo?

How to open the default Contact app in react native using Expo?
my requirements are:
Display a button to open the contact book on home screen.
On clicking the button, open the list of contacts in user's phone.
On contact list, each contact item should display the contact's profile picture, full name and the number/type of number(Home/work)
Add a search bar that will allow the user to search contacts by name
Once the user selects a contact, go back to home screen and display the chosen contact's phone number in a text field(not as an alert/toast).
If a contact has multiple phone numbers, allow the user to pick only one phone number.
import React, { useEffect, useState } from "react";
import {
StyleSheet,
View,
Text,
TextInput,
FlatList,
ActivityIndicator,
} from "react-native";
import * as Contacts from "expo-contacts";
export default function App() {
const [allcontacts, setcontact] = useState([]); //say set main state
const [allcontactsfilter, setcontactfilter] = useState([]); // filter state
const [searchcontact, setsearchcontact] = useState("");
const [loading, setloading] = useState(false);
console.log(searchcontact);
useEffect(() => {
(async () => {
const { status } = await Contacts.requestPermissionsAsync();
if (status === "granted") {
const { data } = await Contacts.getContactsAsync({
fields: [
Contacts.Fields.PhoneNumbers,
// Contacts.Fields.Emails
],
});
// console.log("collectio object", data);
if (data.length > 0) {
// console.log("contact hellos", data);
setcontact(data);
setting same data in two-state help to manipulate state when we do filtering
process
setcontactfilter(data);
setloading(false);
}
}
})();
setloading(true);
}, []);
filter function
const filtercontacts = (e) => {
const filtervalue = allcontactsfilter.filter((contact) => { <-- look here at
allcontactsfilter
let lowercase = `${contact.firstName} ${contact.lastName}`.toLowerCase();
let searchlowercase = e.toLowerCase();
return lowercase.indexOf(searchlowercase) > -1;
});
setsearchcontact(setcontact(filtervalue));
};
return (
<View style={styles.container}>
<TextInput
style={{
backgroundColor: "#D5D5D5",
height: 40,
width: "90%",
borderBottomWidth: 0.3,
borderBottomColor: "#ddd",
}}
placeholder="search"
value={searchcontact}
onChangeText={filtercontacts}
/>
{loading ? (
<View>
<ActivityIndicator size={35} color="green" />
</View>
) : null}
<FlatList
data={allcontacts}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<View style={{ minHeight: 70, padding: 5 }}>
<Text>
{/* {
("inside flatlist>>>,....",
console.log(
item.phoneNumbers == undefined || null
? []
: item.phoneNumbers[0]?.number
))
} */}
{item?.firstName == null
? "please update name in your phone contact book"
: item.firstName}
{item?.lastName == null ? null : item.lastName}
</Text>
<Text style={{ color: "red" }}>
{item.phoneNumbers == undefined || null
? []
: item.phoneNumbers[0]?.number}
</Text>
</View>
)}
ListEmptyComponent={() => (
<Text style={{ fontSize: 20, marginVertical: 40 }}>No contact </Text>
)}
/>
{/* {console.log("okstate..", allcontacts)} */}
<Text>Contacts Module Example </Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
apply style according to your need.

Camera is not running

I’m trying to make a prototype application that over and over
1- record a video with the camera for x seconds
2- displays this video
For this I use the components Camera from expo-camera and Video from expo-av
For this I have two views :
I use in my code the stateSequence property and the sequencer() function which displays alternately the view with the Camera component which films for x seconds , and the video view which allows me to display the video.
Sequencer() is triggered with setInterval( this.sequencer , 10000) found in the componentWillMount()
I can switch alternately from a View with the Camera component to a View with the Video component.
To record a video with the Camera component I use recordAsync(), but I get the following error:
Unhandled promise rejection: Error: Camera is not running
I’m using an android phone for my tests.
Can’t you help me
this is my code
import { StyleSheet, Text, View ,TouchableOpacity} from 'react-native';
import * as Permissions from 'expo-permissions';
import { Camera } from 'expo-camera';
import { Video } from 'expo-av';
import { Logs } from 'expo';
export default class SequenceViewer extends Component {
constructor(props) {
super(props);
this.state = {
stateSequence: "SHOOT ",
hasCameraPermission: null,
type: Camera.Constants.Type.front,
}
this.recordVideo = this.recordVideo.bind(this)
}
sequencer = () => {
if(this.state.stateSequence==="WATCH"){
this.setState({ stateSequence: "SHOOT",})
this.recordVideo(); // Error message Camera is not running
} else {
this.setState({stateSequence: "WATCH"})
}
}
async componentWillMount() {
let rollStatus = await Permissions.askAsync(Permissions.CAMERA_ROLL);
let cameraResponse = await Permissions.askAsync(Permissions.CAMERA)
if (rollStatus.status=='granted'){
if (cameraResponse.status == 'granted' ){
let audioResponse = await Permissions.askAsync(Permissions.AUDIO_RECORDING);
if (audioResponse.status == 'granted'){
this.setState({ permissionsGranted: true });
setInterval( this.sequencer , 10000);
}
}
}
}
recordVideo = async () => {
if(this.state.cameraIsRecording){
this.setState({cameraIsRecording:false})
this.camera.stopRecording();
}
else {
this.setState({cameraIsRecording:true})
if (this.camera) {
let record = await this.camera.recordAsync(quality='480p',maxDuration=5,mute=true).then( data =>{
this.setState( {recVideoUri :data.uri})
})
}
}
};
render() {
const { hasCameraPermission } = this.state
if(this.state.stateSequence=="WATCH")
{
return(
<View style={styles.container}>
<Video
source={{ uri:this.state.recVideoUri }}
rate={1.0}
volume={1.0}
isMuted={false}
resizeMode="cover"
shouldPlay
isLooping
style={{ width: 300, height: 300 }}
ref={(ref) => { this.player = ref }}
/>
</View>
)
} else
{
return(
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type} ref={ref => {this.camera = ref; }}></Camera>
</View>
)
}
}
}
const styles = StyleSheet.create({
viewerText: {
fontSize: 20,
fontWeight: 'bold',
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Thank you
I had the same problem, my solution was by default camera type have to be "back" and you could change to "front" by:
componentDidMount = () => {
this.props.navigation.addListener('didFocus', async () => {
await setTimeout(() => {
this.setState({ cameraType: Camera.Constants.Type.front })
}, 100)
});
}
I was getting the "Camera is not running" error when i changed screens. So for functional components instead of withNavigationFocus(Camera) use this method:
import { useIsFocused } from '#react-navigation/native';
function MyComponent() {
const isFocused = useIsFocused()
return (
<View>
{ isFocused && <RNCamera /> }
</View>
)
}

Categories

Resources