Real-time line charting with React-Native - android

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

Related

The solution for the picker issue appears loading, how to fix it?

That's my code which was fixed in the previous question, and still the error occurs, the data is not showing just showing loading, how to fix that ?
const Sub_Map = () => {
const [hasLoaded, setHasLoaded] = useState(false);
const [data, setdata] = useState();
useEffect(() => {
const callApi = async () => {
await getData();
setHasLoaded(true);
};
callApi();
}, []);
const getData = () => {
fetch('http:// . . . ./aplikasi/restapi.php?op=getJenis')
.then(response => response.json())
.then(json => {
// console.log(json);
setdata(json);
// console.log(data);
});
};
Maybe there is another correction for the return part?
return (
<View style={styles.container}>
<Text style={styles.text}>Pilih Data</Text>
<View style={styles.picker}>
{hasLoaded ? (
<ActivityIndicator />
) : (
<Picker
selectedValue={data}
onValueChange={itemValue => setdata(itemValue)}>
{data &&
data?.map((item, key) => {
<Picker.Item
label={'${item.bencana}'}
value={'${item.ID }'}
key={key}
/>;
})}
</Picker>
)}
</View>
);
};
and this is for API , there may be a correction
function getJenis()
{
global $conn;
global $json;
global $obj;
$sql = mysqli_query($conn, "SELECT * FROM bencana_detail ORDER BY bencana ASC");
while ($row = mysqli_fetch_array($sql)) {
$hasil[] = array(
'ID' => $row['id_bencana_detail'],
'bencana' => $row['bencana']
);
}
echo json_encode($hasil);
}
Try this it should work
{data.length <= 0 ? (
<ActivityIndicator />
) : (
<Picker
selectedValue={data}
onValueChange={itemValue => setdata(itemValue)}>
{data &&
data?.map((item, key) => {
<Picker.Item
label={'${item.bencana}'}
value={'${item.ID }'}
key={key}
/>;
})}
</Picker>
)}

About react native vision camera taking picture and save

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)

Why doesn't the called API data appear in the native picker?

Why doesn't the called API data appear in the native picker? ,
Previously there was an ActivityIndicator and it was only loading, then I deleted the ActivityIndicator but the API data didn't appear, but the console.log data was called, why?
const [data, setdata] = useState();
useEffect(() => {
const callApi = async () => {
await getData();
};
callApi();
}, []);
,,,,
,,,,
return (
<View style={styles.container}>
<Text style={styles.text}>Pilih Data</Text>
<View style={styles.picker}>
<Picker
selectedValue={data}
onValueChange={itemValue => setdata(itemValue)}>
{data &&
data?.map((item, key) => {
<Picker.Item
label={'${item.bencana}'}
value={'${item.ID }'}
key={key}
/>;
})}
</Picker>
</View>
)

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.

Android problem with expo-google-app-auth

I have a problem with expo-google-app-auth in Android. It's work perfectly fine with IOS.
After successful sign in in Android instead of redirect me back to my app LoggedInPage component, I'm again in LoginPage component. I think it's because Android opens application again and I'm losing the state, so I'm also losing the states from login and I have to sign in again...
In IOS it just sign me in an redirecting to LoggedInPage component perfectly..
import React, { useState } from "react";
import * as Google from "expo-google-app-auth";
import { StyleSheet, Text, View, Image, Button } from "react-native";
export default function App() {
const [signedIn, setSignIn] = useState(false);
const [name, setName] = useState("");
const [photoUrl, setPhotoUrl] = useState("");
signIn = async () => {
try {
console.log("Sign in 1");
const result = await Google.logInAsync({
androidClientId:
“<< android client id >>apps.googleusercontent.com",
iosClientId:
“<< iOS client id >>.apps.googleusercontent.com",
scopes: ["profile", "email"]
});
console.log("Sign in 2");
console.log("Result: ", result);
if (result.type === "success") {
setSignIn(true);
setName(result.user.name);
setPhotoUrl(result.user.photoUrl);
return result.accessToken;
} else {
return { cancelled: true };
}
} catch (e) {
return { error: true };
}
};
const LoginPage = () => {
console.log("Inside LoginPage");
return (
<View>
<Text style={styles.header}>Sign In With Google</Text>
<Button title="Sign in with Google" onPress={() => signIn()} />
</View>
);
};
const LoggedInPage = () => {
return (
<View style={styles.container}>
<Text style={styles.header}>Welcome:{name}</Text>
<Image style={styles.image} source={{ uri: photoUrl }} />
</View>
);
};
console.log("SignedIn: ", signedIn);
return (
<View style={styles.container}>
{signedIn ? <LoggedInPage /> : <LoginPage />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
},
header: {
fontSize: 25
},
image: {
marginTop: 15,
width: 150,
height: 150,
borderColor: "rgba(0,0,0,0.2)",
borderWidth: 3,
borderRadius: 150
}
});
Any ideas/guidance how should I fix my app in Android ?
You need to add a redirectUrl:
const result = await Google.logInAsync({
androidClientId:
“<< android client id >>apps.googleusercontent.com",
iosClientId:
“<< iOS client id >>.apps.googleusercontent.com",
scopes: ["profile", "email"],
redirectUrl: "{Your Bundle ID (com.example.app)}:/oauth2redirect/google",
});

Categories

Resources