On my expo ejected project, im trying to use expo-contacts with no success.
"react-native": "~0.61.5",
"expo": "~37.0.3",
i ran expo install expo-contacts
import * as Permissions from 'expo-permissions';
import * as Contacts from 'expo-contacts';
getContact = async () => {
try {
let { status } = await Permissions.askAsync(Permissions.CONTACTS);
if (status === 'granted') {
const { data } = await Contacts.getContactsAsync({
fields: [Contacts.Fields.Emails],
});
console.log("getContact / data: ", data);
if (data.length > 0) {
const contact = data[0];
console.log("getContact / contact: ", contact);
}
}
} catch(e){
console.log("getContact / error: ", e)
}
}
<TouchableOpacity style={{ marginTop: 20 }} onPress={() => this.getContact()}>
<Image source={contactsIcon} style={{ width: 30, height: 30 }} />
</TouchableOpacity>
Have you set up the permissions in your AndroidManifest.xml as follows:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
Also take a note that: "For bare React Native projects, you must ensure that you have installed and configured the react-native-unimodules [1] package before continuing."
[1] https://github.com/expo/expo/tree/master/packages/react-native-unimodules
Related
I used for the first time react-native-ble-manager.
The app has all the permissions, however when I run the BleManager.scan() the app is closing without any error or logs.
I know the code is a little ugly but it's just for testing, the first second I run the bluetooth manager start and after 5 seconds I run the scan.
But the crash happen immediately after 5 seconds.
Any idea why?
import BleManager from 'react-native-ble-manager';
const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);
const handleDiscoverPeripheral = (peripheral) => {
console.log('Got ble peripheral', peripheral);
if (!peripheral.name) {
peripheral.name = 'NO NAME';
}
peripherals.set(peripheral.id, peripheral);
setList(Array.from(peripherals.values()));
}
const handleStopScan = () => {
console.log('Scan is stopped');
}
let interval;
let gImageShow = true;
let gTime = 0;
BleManager.enableBluetooth()
.then(() => {
// Success code
console.log("The bluetooth is already enabled or the user confirm");
})
.catch((error) => {
// Failure code
console.log("The user refuse to enable bluetooth");
});
function App(props) {
const [shouldShow, setShouldShow] = useState(gImageShow);
useEffect(() => {
interval = setInterval(() => {
if (gTime == 1)
{
BleManager.start({showAlert: true});
bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral);
bleManagerEmitter.addListener('BleManagerStopScan', handleStopScan );
PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("Permission is OK");
}
});
}
if (gTime == 5)
{
BleManager.scan([], 10, true);
}
gImageShow = !gImageShow;
setShouldShow(gImageShow);
gTime = gTime + 1;
},1000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
});
the manifest is like:
xmlns:tools="http://schemas.android.com/tools"
package="com.diagnostic_ble">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="28"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:targetApi="Q"/>
<!-- Needed only if your app looks for Bluetooth devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
The problem has been solved. The new android 12 (I think from this one), needs a different permission that it hasn't been updated in react-native-ble-manager webpage.
In the manifest you need to add
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
Also, In the app.js you need to call once requestPermissions();
that it can be like
const requestPermissions = async () => {
if (Platform.OS === 'android') {
const apiLevel = await DeviceInfo.getApiLevel();
if (apiLevel < 31) {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Permission',
message: 'Bluetooth Low Energy requires Location',
buttonNeutral: 'Ask Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
} else {
const result = await requestMultiple([
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
]);
const isGranted =
result['android.permission.BLUETOOTH_CONNECT'] ===
PermissionsAndroid.RESULTS.GRANTED &&
result['android.permission.BLUETOOTH_SCAN'] ===
PermissionsAndroid.RESULTS.GRANTED &&
result['android.permission.ACCESS_FINE_LOCATION'] ===
PermissionsAndroid.RESULTS.GRANTED;
}
} else {
}
};
I have created a react-native app in VS Code. The app is running fine in the browser with expo. Generated a keystore file and created an .apk with gradlew assembleRelease.
The .apk can be installed on my Android tablet. But after starting the app, it is not running and the splash screen is shown (see image below).
The SDK version on the tablet (30) is higher than the minSdkVersion (21) of the app.
Also added <uses-feature android:name="android.hardware.telephony" android:required="false" /> to the AndroidManifest.xml file.
Code is as follows.
index.js:
import { registerRootComponent } from 'expo';
import App4 from './App4';
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App4);
App4.js:
import React from 'react'
import List from './List.js'
const App = () => {
return (
<List />
)
}
export default App
List.js:
import React, { Component } from 'react'
import { Text, View, TouchableOpacity, StyleSheet, Image } from 'react-native'
class List extends Component {
state = {
products: []
}
componentDidMount() {
this.GetAllProducts();
}
GetAllProducts() {
//fetch("http://192.168.2.14:3000/getallproducts")
fetch("https://categoriesexpress444.herokuapp.com/getallproducts")
.then(res => res.json())
.then(jsonresult => {
this.setState({
products: jsonresult
});
console.log(this.state.products);
});
}
getsrcPath(string) { // this function distinguishes between images in UserImages folder and images on Cloudinary
var firstChar = string.charAt(0);
if (firstChar == '~') { // image is in UserImages folder and item.picture path starts wih ~/UserImages/
return string.substring(1, string.length);
}
else { // image is at Cloudinary and item.picture starts with http://
return string;
}
}
render() {
return (
<View>
{
this.state.products.map((item, index) => (
<TouchableOpacity
key = {item.id}
style = {styles.container}>
<Text style = {styles.text}>{item.productname}</Text>
<Text>{item.description}</Text>
<Text>€ {item.price}</Text>
<img src={this.getsrcPath(item.picture)} />
<Text style = {styles.text}>
{item.name}
</Text>
</TouchableOpacity>
))
}
</View>
)
}
}
export default List
const styles = StyleSheet.create ({
container: {
padding: 10,
marginTop: 3,
backgroundColor: '#ffffff',
alignItems: 'center',
cursor: 'none'
},
text: {
color: '#4f603c'
}
})
If you are using expo to create react native app then
you have to build an app over the expo using this command
expo build:adroid or expo build:ios
once the build will successfully create you will get one URL then you can use the URL to install the app on your device.
If you are using react-native-cli to create react native app then
you have to build an app over the expo using this command
./gradlew assembleRelease or ./gradlew assembleDebug in MacOs
I have troubles having audio permissions to work on android build. It works fine in expo go, but not in android build.
In the given code, the permission for the camera is asked properly, but when accepted the permission for audio shows only for a fraction of a second and return a not granted status.
Once again, it works fine in expo go.
Is there anything i’m doing wrong ? do you have an idea on how to solve this ?
Thanks you very much community !
SDK Version: 41
Platforms(Android/iOS/web/all): Android (samsung A20e)
import {Camera} from 'expo-camera'
import {Audio} from 'expo-av';
export default () => {
return (
<View>
<Button
onPress={() => {
Camera.requestPermissionsAsync().then((status) => {
// audio permission request is only shown for half a second in build mode and is automatically denied permission
Audio.requestPermissionsAsync().then((status) => {
console.log('ok');
});
});
}}>
Test
</Button>
</View>
);
};
Use it like this
Working Example Here
import { Camera } from 'expo-camera';
import { Audio } from 'expo-av';
const GetPermissions = async () => {
try {
console.log('Requesting permissions..');
const CameraPerm = await Camera.requestPermissionsAsync();
if (CameraPerm.status === 'granted') {
console.log('Camera Permission Granted');
}
const AudioPerm = await Audio.requestPermissionsAsync();
if (AudioPerm.status === 'granted') {
console.log('Audio Permission Granted');
}
} catch (err) {
console.error('Failed to get permissions', err);
}
};
return (
<View style={styles.container}>
<Button title="Get Permissions" onPress={GetPermissions} />
</View>
);
Make sure all the imports are correct
be sure to have either both or none in your app.json
that was my problem !
I am trying to use the react-native-live-audio-stream library. However I get errors with the permission of the microphone.
I am following this exact link on how to set it up.
This is my recorder component:
import React from 'react';
import {TouchableOpacity, View} from 'react-native';
import LiveAudioStream from 'react-native-live-audio-stream';
export default function Recorder() {
const options = {
sampleRate: 32000, // default is 44100 but 32000 is adequate for accurate voice recognition
channels: 1, // 1 or 2, default 1
bitsPerSample: 16, // 8 or 16, default 16
audioSource: 6, // android only (see below)
};
LiveAudioStream.init(options);
LiveAudioStream.on('data', (data) => {
// base64-encoded audio data chunks
});
return (
<View>
<TouchableOpacity onClick={LiveAudioStream.start()}>
<Text>Start recording!</Text>
</TouchableOpacity>
</View>
);
}
The error I get is:
startRecording() called on an uninitialized AudioRecord.
So I start investigating the permission thing... This is what I've got so far:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="Manifest.permission.RECORD_AUDIO"/>
in AndroidManifest.xml
By adding a request for the microphone like this:
const requestMicrophone = async () =>{
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.RECORD_AUDIO},
REQUEST_MICROPHONE);
}
I get the error of:
[![ActivityCompat.requestPermissions(getActivity(),new String\[\]{Manifest.permission.RECORD_AUDIO},
REQUEST_MICROPHONE]2]2
Any ideas on how to fix this?
EDIT:
I fixed the error! The audio related things in the recorder needs to be put in a function which is called by starting the recording.
Try this code for taking permission in android:
import {PermissionsAndroid, Platform} from 'react-native';
.....
const requestMicrophone = async () => { //replace your function with this code.
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
{
title: 'Permissions for record audio',
message: 'Give permission to your device to record audio',
buttonPositive: 'ok',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('permission granted');
} else {
console.log('permission denied');
return;
}
} catch (err) {
console.warn(err);
return;
}
}
}
First you are using onClick event its react event not react native you should switch to onPress event also you are invoking LiveAudioStream.start() with each render by using start()
<View>
<TouchableOpacity onClick={LiveAudioStream.start()}>
<Text>Start recording!</Text>
</TouchableOpacity>
</View>
//edited
<View>
<TouchableOpacity onPress={()=>LiveAudioStream.start}>
<Text>Start recording!</Text>
</TouchableOpacity>
</View>```
I want to send sms to multiple numbers without opening to default messaging app.
I try to use react-native-sms-x but its not maintained and my project just stuck at compiling.
Also I used react-native-sms but it open default Messaging App filled with one user number and message body and had to click send button of it too.
import { Linking,Platform } from "react-native";
const url = (Platform.OS === 'android')
? 'sms:919999999999?body=your message'
: 'sms:919999999999'
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log('Unsupported url: ' + url)
} else {
return Linking.openURL(url)
}
}).catch(err => console.error('An error occurred', err))
After a lot of research and trials in the react app...
I have found this library working fine and reached the goals to send a message without going into the default message environment.
var phoneNumbers = {
"addressList": ["+911212121212", "+911212121212"]
};
var message = "This is automated test message"
SmsAndroid.autoSend(
phoneNumbers,
message,
(fail) => {
console.log('Failed with this error: ' + fail);
},
(success) => {
console.log('SMS sent successfully');
},
);
I hope it helps you. Do not forget to upvote
From Now Just For Android I use react-native-sms-android
Here is my Code for Sending sms to multiple users:
import Asms from "react-native-sms-android";
type Props = {};
export default class App extends Component<Props> {
constructor(Props) {
super(Props);
this.state = { FileNumbers: ['687867867867','8575774433'], Message:
"gjjgjgj" };
}
sendingSms = (Receivers, Messagex) => {
try {
Receivers.map(
async Numbers =>
await Asms.sms(Numbers, Messagex, "sendDirect", (err,message)
=> {
if (err) {
console.log(err);
} else {
console.log(message);
}
})
);
} catch (e) {
alert("" + e);
}
};
render() {
return (
<View style={styles.container}>
<TextInput
style={{
height: 40,
borderColor: "gray",
borderWidth: 1,
width: "90%"
}}
onChangeText={Message => this.setState({ Message })}
value={this.state.Message}
/>
<Button
title="SEND"
onPress={() =>
this.sendingSms(this.state.FileNumbers, this.state.Message)
}
/>
</View>
);
}
}