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>```
Related
I am new in React Native, so I don't master all related to background tasks, when I have to keep the app track playing even the user locks or hibernates his device.
Actually I achieved in a project that just plays a bundle track, like you can see:
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { Audio } from 'expo-av';
export default function App() {
const [sound, setSound] = React.useState();
async function playSound() {
console.log('Loading Sound');
//On function below, could be used the following line below to get some file from ./assets folder, from device storage using require()
//method, or using loadAsync({uri:url}) to get the file from web by its url, what can be noticed in the delimited block with "*** ***"
//const { sound } = await Audio.Sound.createAsync( require('./assets/Hello.mp3')
//***
const sound = new Audio.Sound();
await sound.loadAsync({
uri: 'https://sound-library.net/wp-content/uploads/2022/08/oneheart-reidenshi-snowfall.mp3',
});
//***
setSound(sound);
console.log('Playing Sound');
await sound.playAsync();
}
React.useEffect(() => {
return sound
? () => {
console.log('Unloading Sound');
sound.unloadAsync();
}
: undefined;
}, [sound]);
return (
<View style={styles.container}>
<Button title="Play Sound" onPress={playSound} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I would like to know how I could do that with this feature.
I'm new to react native and in my sample app I can't handle properly results returned from ImagePicker of this component https://github.com/react-native-image-picker/react-native-image-picker
I'm running react 0.65 and below is my code:
import * as ImagePicker from 'react-native-image-picker';
export class App extends Component {
constructor() {
super();
this.state = { imageSource: null };
}
selectImage = () => {
const selectImageFromGallery = async () => {
const response = await ImagePicker.launchImageLibrary('library', {
selectionLimit: 1,
mediaType: 'photo',
includeBase64: true,
});
const {img64base} = response.assets[0];
this.setState({img64base});
};
selectImageFromGallery();
// console.log(resp);
}
render() {
return (
<SafeAreaView style={{justifyContent: 'center', alignItems: 'center'}}>
<Button title='Select from gallery' onPress={() => this.selectImage()} />
<Image source={this.state.imageSource} />
</SafeAreaView>
);
};
}
Upon run of application I can press button and select image, but whenever I confirm my selection it is throwing error in console and on the screen of Android device:
Uncaught Error:
'Type Error: callback is not a function'
This call stack is not sybmolicated.
I do understand that I miss to handle correctly promise or callback but I cant figure out correct syntax. Could you please help? Tried zillion of times with 'await', without await, etc. The only thing I need to stay with component class and I won't change to function class - have single calls in componentDidMount functions to make sure some specific hardware is called only once. Pease help
selectImage = async () {
const response = await ImagePicker.launchImageLibrary('library', {
selectionLimit: 1,
mediaType: 'photo',
includeBase64: true,
});
const {img64base} = response.assets[0];
this.setState({img64base});
}
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'm trying to ask for runtime permission in ReactNative, but I'm always getting a "Permission is null" error in device screen.
here is the code:
import React, {Component} from 'react';
import {Text, View, StyleSheet, TextInput, Button} from 'react-native';
import {PermissionsAndroid} from 'react-native';
export default class HomeScreen extends React.Component {
componentDidMount()
{
PermissionsAndroid.request(PermissionsAndroid.READ_PHONE_STATE)
}
render () {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>Seja Bem vindo a BBTS!</Text>
<Text style={styles.paragraph}>
Matricula: {this.props.navigation.state.params.matricula}
</Text>
<Text style={styles.paragraph}>
Email: {this.props.navigation.state.params.email}
</Text>
<Text style={styles.paragraph}>
imei vem aqui
</Text>
</View>
);
}
}
I already put this on android manifest. My APi target is 26.
Any ideias?
Solution:
async requestPermission() {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can read the phone state")
} else {
console.log("permission denied")
}
} catch (err) {
console.warn(err)
}
}
componentDidMount()
{
this.requestPermission();
}
While you do need to handle the promise as #Daniel says the reason for the error is that your permissions request is incorrect, it should be:
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE)
The request() method returns a promise. You'll either need to async/await or .then()/.catch() and then check PermissionsAndroid.RESULTS.GRANTED. That may either fix your problem or help you debug.
Using https://github.com/MacKentoch/react-native-beacons-manager
Works lovely on iOS, however, on Android, after I begin ranging beacons, the beacon array shows up with nothing in it (there are 6 beacons next to me and they all show up on iOS).
Here's what I'm doing:
componentDidMount() {
// Start detecting all iBeacons in the nearby
Beacons.detectIBeacons();
Beacons.startRangingBeaconsInRegion('Estimotes', 'B9407F30-F5F8-466E-AFF9-25556B57FE6D').then((data)=>{
console.log(data);
}).catch((reason) => {
console.log(reason);
});
// Print a log of the detected iBeacons (1 per second)
DeviceEventEmitter.addListener('beaconsDidRange', (data) => {
console.log(data);
});
}
In my console, I get this:
{beacons: Array(0), uuid: "b9407f30-f5f8-466e-aff9-25556b57fe6d", identifier: "Estimotes"}
I left the UUID of the Estimotes as default so this should work. Using a Samsung Galaxy S8+ for testing. Am I doing anything wrong coding wise here? Are there additional permissions on Android that I am missing? Bluetooth and Location services are on.
Alright, I figured it out. Newer versions of android require additional permissions. In your Manifest, throw this guy in there:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
.... if you're using react-native-kontaktio (which is better than react-native-beacons-manager imo) you'll also need to throw this in your Manifest in the <application> section:
<service android:name="com.kontakt.sdk.android.ble.service.ProximityService"/>
Then in your app.js you'll need to request the permission like () make sure you
import PermissionsAndroid
from 'react-native'
:
componentDidMount() {
try {
const granted = PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'Location Permission',
'message': 'Activeev needs to access your location.'
}
)
console.log('here', granted);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("Location Permitted")
} else {
console.log("Location permission denied")
}
} catch (err) {
console.warn(err)
}
}
Working like a charm now. Hope this helps someone else.
Thank you for your answer. It definitely worked. Based on your answer, below is my implementation.
import React, { Component } from 'react';
import { View, DeviceEventEmitter, ListView , Text} from 'react-native';
import Beacons from 'react-native-beacons-manager';
import {PermissionsAndroid} from 'react-native'
export default class App extends Component {
async componentDidMount() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'Location Permission',
'message': 'Activeev needs to access your location.'
}
)
console.log('here', granted);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("Location Permitted")
// Start detecting all iBeacons in the nearby
Beacons.detectIBeacons();
Beacons.startRangingBeaconsInRegion('test', '85d37dd8-a9dc-48a8-ab1c-b86fcb7a6a17').then((data)=>{
console.log(data);
})
.catch((reason) => {
console.log(reason);
});
// Print a log of the detected iBeacons (1 per second)
DeviceEventEmitter.addListener('beaconsDidRange', (data) => {
console.log(data);
});
} else {
console.log("Location permission denied")
}
}catch (err) {
console.warn(err)
}
}
render(){
return(
<View></View>
);
}
}