Expo: Audio.requestPermissions in android build - android

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 !

Related

How to Open External App from Android using React Native?

I'm trying to open up an external app from my react native app, but it only seems to be working on my iPhone and not my Android. The console.log shows "isInstalled false" for Android but "isInstalled True" for iPhone.
I want the react native app to check if the user has the external app installed on their phones already. If so, open the external app, and if not, the app will redirect the user to Google Play (Android) / App Store (iOS).
import { Linking, Platform } from 'react-native';
import { Header, Card } from 'react-native-elements';
import { SafeAreaView } from 'react-native-safe-area-context';
import { AppInstalledChecker } from 'react-native-check-app-install';
export default function App() {
return (
<SafeAreaView style={styles.container}>
<Card containerStyle={styles.cardStyle}>
<Card.Image
style={styles.image}
source={{
uri:"https://play-lh.googleusercontent.com/T0OPODRs2EciPVEwUHv4Xucn5_MMQ8pHzEII1THqiIa8ef3XaZ1rf-TWW1g10SvJ0w=s180-rw"
}}
onPress={()=>{
const iOSAppStoreUrl = 'https://apps.apple.com/sg/app/hdb-health/id1266210350'
const iOSGoogleStoreUrl = 'https://play.google.com/store/apps/details?id=com.hdb.healthAnd'
if( Platform.OS === 'ios'){
AppInstalledChecker
.checkURLScheme('hdbhealth')
.then((isInstalled) => {
Linking.openURL('hdbhealth://app')
})
.catch(Linking.openURL(iOSAppStoreUrl))
} else { // Android
AppInstalledChecker
.checkURLScheme('com.hdb.healthAnd')
.then((isInstalled) => {
Linking.openURL('hdbhealth://app')
})
.catch(Linking.openURL(iOSGoogleStoreUrl))
}
}}
/>
</Card>
</SafeAreaView>
);
}
You should use isAppInstalledAndroid instead of checkURLScheme for android.
https://github.com/redpandatronicsuk/react-native-check-app-install

Why navigator.geolocation.getcurrentposition is not available with react native and expo

I am trying to get some position information from a device, I am using React-native, Expo, and ExpoGo on android mobile, I am not using simulators, the application is working with ExpoGo on Android, but geolocation is not working, it sends this error message every time:
window.navigator.geolocation.getCurrentPosition is not available. Import and execute installWebGeolocationPolyfill() from expo-location to add it, or use the expo-location APIs instead.
Please help me find the solution to this issue.
This is the App code used:
import { Text, View} from "react-native";
import styles from "./styles";
const API_KEY = "";
const URL = `https://maps.google.com/maps/api/geocode/json?key=${API_KEY}&latlng=`;
export default function WhereAmI() {
const [address, setAddress] = useState("loading...");
const [longitude, setLongitude] = useState();
const [latitude, setLatitude] = useState();
useEffect(() => {
function setPosition({ coords: { latitude, longitude } }) {
setLongitude(longitude);
setLatitude(latitude);
fetch(`${URL}${latitude},${longitude}`)
.then(
(resp) => resp.json(),
(e) => console.error(e)
)
.then(({ results }) => {
setAddress(results[0].formatted_address);
});
}
navigator.geolocation.getCurrentPosition(setPosition);
let watcher = navigator.geolocation.watchPosition(
setPosition,
(err) => console.error(err),
{ enableHighAccuracy: true }
);
return () => {
navigator.geolocation.clearWatch(watcher);
};
});
return (
<View style={styles.container}>
<Text style={styles.label}>Address: {address}</Text>
<Text style={styles.label}>Latitude: {latitude}</Text>
<Text style={styles.label}>Longitude: {longitude}</Text>
</View>
);
}
I fixed this problem, and this worked for me.
geolocation on iOS and Android:
I installed the expo-location package by running expo install expo-location.
I imported expo location in App.js as Location: import * as Location from 'expo-location'.
I used the #installWebGeolocationPolyfill function that polyfills #navigator.geolocation for interop with the core React Native
and Web API approach to geolocation just before using of the #navigator.geolocation.getCurrentPosition like
this:
# ... some code
Location.installWebGeolocationPolyfill()
navigator.geolocation.getCurrentPosition(setPosition);
# ... some code
2.The error 'formatted_address' is undefined:
That because there is no API_KEY, you should get an API key from Google, instead, I just Added it manually into the #setPosition function like this:
#...some code
.then(
({ results }) => {
results[0]={formatted_address:"here"}
setAddress(results[0].formatted_address)
},
#...some code

Cannot access permission to microphone

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>```

how can i access current location from web-page in react native webview

I have an app which developed in react-js. I want to integrate this app into react-native-webview. everything I right but I have two problems.
1-how can I access current location of the user in react-native-webview.
2-how can I debug my react-js(webpage) app inside react-native-webview.
for first problem
if I run webpage in a mobile browser and click on that event I'm getting current location of the user and at the same time when my react-native app getting started, I'm invoking permission for current location so in react-native-debugger i'm getting current location of user.i followed the similar example but this is related to react-native.
exact problem is how can I access the current location of webview in react-native-webview
for second problem
when I'm clicking on the event to fetch current location it is not showing the current location so ** I want to see what is error/response of that event**. because it is in webview I can access react-native logs in react-native-debugger but cannot see the web view logs in the debugger.I followed this one also but I don't know where to put that android config code.
my react-native code
import React, {Component} from 'react';
import {PermissionsAndroid} from 'react-native';
import { WebView } from "react-native-webview";
export default class App extends Component {
constructor(props){
super(props);
// To see all the requests in the chrome Dev tools in the network tab.
XMLHttpRequest = GLOBAL.originalXMLHttpRequest ?
GLOBAL.originalXMLHttpRequest :
GLOBAL.XMLHttpRequest;
// fetch logger
global._fetch = fetch;
global.fetch = function (uri, options, ...args) {
return global._fetch(uri, options, ...args).then((response) => {
console.log('Fetch', { request: { uri, options, ...args }, response });
return response;
});
};
}
async requestLocationPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'Location Access Permission',
'message': 'Stanplus would like to use your location ' +
'so you we track you.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the location");
if (typeof window !== 'undefined' && typeof window.navigator !== 'undefined' && navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
console.log(position.coords.latitude,'success');
},
(error) => {
console.log(error,'fail')
},
{ enableHighAccuracy: false, timeout: 5000, maximumAge: 10000 }
);
}
} else {
console.log("Location permission denied")
}
} catch (err) {
console.warn(err)
}
}
componentDidMount() {
this.requestLocationPermission();
}
render() {
return (
<WebView
source={{uri: 'https://3fa4f958.ngrok.io/steptwo'}}
style={{marginTop: 20}}
onMessage={(event)=> console.log(event.nativeEvent.data)}
scalesPageToFit={true}
javaScriptEnabled = {true}
/>
);
}
}
my React.js code which accesses current location
if (navigator.geolocation) {
alert('event clicked');//in react-native app its showing the alert
navigator.geolocation.getCurrentPosition(
//but inside here react-native can't execute because of location permission issue
position => {
let latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let geocoder = new window.google.maps.Geocoder();
//do other stuff----------
}
)
}
** I want to fetch current location when user click on webpage event inside react-native app and how to debug webview code**
please help stuck since 2 days ):
A few steps are needed to get it working on Android.
Add this line to your AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And then in your app you'll need to request location once before the webview can request it. Do it like so in your view:
import { PermissionsAndroid } from 'react-native';
...
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Access Permission',
message: 'We would like to use your location',
buttonPositive: 'Okay'
}
);
And then also on your webview add the property:
geolocationEnabled={true}
you need to add geolocationenabled https://facebook.github.io/react-native/docs/webview#geolocationenabled

react-native-beacons-manager Not showing any beacons on Android

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>
);
}
}

Categories

Resources