Get user location on app running as well as if app is in background - react-native

I'm beginner in React Native, I'm using expo I want to ask user for permission to access location if user granted the permission it will check if phone location from setting is on or not if it is on then it will give it's current location and if the app is close or running in background it will still give location
I have tried but it's not working
import React, { Component } from "react";
import {
Platform,
Text,
View,
StyleSheet,
Linking,
Button,
AppState
} from "react-native";
import Constants from "expo-constants";
import * as TaskManager from "expo-task-manager";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import * as IntentLauncher from "expo-intent-launcher";
import { Alert, NavigationActions } from "react-native";
import Modal from "react-native-modal";
const LOCATION_TASK_NAME = "background-location-task";
export default class LocationScreen extends Component {
state = {
location: null,
errorMessage: null,
};
componentDidMount = async () => {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Balanced
});
render() {
let text = "Waiting..";
if (this.state.errorMessage) {
text = this.state.errorMessage;
} else if (this.state.location) {
text = JSON.stringify(this.state.location);
}
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{text}</Text>
</View>
);
}
}
TaskManager.defineTask(LOCATION_TASK_NAME, handel);
export async function handel({ data, error }) {
try {
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== "granted") {
this.setState({
errorMessage: "Permission to access location was denied"
});
return;
} else {
if (data) {
const { locations } = data;
const location = locations.map(location => {
let newLocation = Location.reverseGeocodeAsync(location.coords).then(
data => {
let maplocation = data.map(location => {
console.log(location);
console.log(location.city);
});
}
);
});
}
}
} catch (error) {
let status = Location.getProviderStatusAsync();
if (!status.locationServiceEnabled) {
const { navigation } = this.props;
navigation.navigate("Login");
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
paddingTop: Constants.statusBarHeight,
backgroundColor: "#ecf0f1"
},
paragraph: {
margin: 24,
fontSize: 18,
textAlign: "center"
}
});
This is only working if location is on. It's not asking for permission if location is off or not granted

Related

Issue sending & receiving streams between two clients in LiveKit's React Native SDK

I'm trying to build on the example app provided by livekit, so far I've implemented everything like the example app and I've been successful with connecting to a room on example website, I recieve audio from website, but I don't read the video stream, and I also can't send audio or video at all.
Steps to reproduce the behavior:
add the following to index.js
import { registerRootComponent } from "expo";
import { registerGlobals } from "livekit-react-native";
import App from "./App";
registerRootComponent(App);
registerGlobals();
Rendering the following component in App.tsx
import { Participant, Room, Track } from "livekit-client";
import {
useRoom,
useParticipant,
AudioSession,
VideoView,
} from "livekit-react-native";
import { useEffect, useState } from "react";
import { Text, ListRenderItem, StyleSheet, FlatList, View } from "react-native";
import { ParticipantView } from "./ParticipantView";
import { RoomControls } from "./RoomControls";
import type { TrackPublication } from "livekit-client";
const App = () => {
// Create a room state
const [, setIsConnected] = useState(false);
const [room] = useState(
() =>
new Room({
publishDefaults: { simulcast: false },
adaptiveStream: true,
})
);
// Get the participants from the room
const { participants } = useRoom(room);
const url = "[hard-coded-url]";
const token =
"[hard-coded-token";
useEffect(() => {
let connect = async () => {
// If you wish to configure audio, uncomment the following:
await AudioSession.configureAudio({
android: {
preferredOutputList: ["speaker"],
},
ios: {
defaultOutput: "speaker",
},
});
await AudioSession.startAudioSession();
await room.connect(url, token, {});
await room.localParticipant.setCameraEnabled(true);
await room.localParticipant.setMicrophoneEnabled(true);
await room.localParticipant.enableCameraAndMicrophone();
console.log("connected to ", url);
setIsConnected(true);
};
connect();
return () => {
room.disconnect();
AudioSession.stopAudioSession();
};
}, [url, token, room]);
// Setup views.
const stageView = participants.length > 0 && (
<ParticipantView participant={participants[0]} style={styles.stage} />
);
const renderParticipant: ListRenderItem<Participant> = ({ item }) => {
return (
<ParticipantView participant={item} style={styles.otherParticipantView} />
);
};
const otherParticipantsView = participants.length > 0 && (
<FlatList
data={participants}
renderItem={renderParticipant}
keyExtractor={(item) => item.sid}
horizontal={true}
style={styles.otherParticipantsList}
/>
);
const { cameraPublication, microphonePublication } = useParticipant(
room.localParticipant
);
return (
<View style={styles.container}>
{stageView}
{otherParticipantsView}
<RoomControls
micEnabled={isTrackEnabled(microphonePublication)}
setMicEnabled={(enabled: boolean) => {
room.localParticipant.setMicrophoneEnabled(enabled);
}}
cameraEnabled={isTrackEnabled(cameraPublication)}
setCameraEnabled={(enabled: boolean) => {
room.localParticipant.setCameraEnabled(enabled);
}}
onDisconnectClick={() => {
// navigation.pop();
console.log("disconnected");
}}
/>
</View>
);
};
function isTrackEnabled(pub?: TrackPublication): boolean {
return !(pub?.isMuted ?? true);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
stage: {
flex: 1,
width: "100%",
},
otherParticipantsList: {
width: "100%",
height: 150,
flexGrow: 0,
},
otherParticipantView: {
width: 150,
height: 150,
},
});
export default App;
the components used here are mostly the same as what's in the example, I've removed the screensharing logic and the messages
5. I run the app using an expo development build
6. it will log that it's connected, you'll be able to hear sound from the remote participant, but not see any video or send any sound.
7. if i try to add
await room.localParticipant.enableCameraAndMicrophone();
in the useEffect, I get the following error:
Possible Unhandled Promise Rejection (id: 0):
Error: Not implemented.
getSettings#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:103733:24
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:120307:109
generatorResume#[native code]
asyncGeneratorStep#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21908:26
_next#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21927:29
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21932:14
tryCallTwo#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26656:9
doResolve#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26788:25
Promise#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26675:14
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21924:25
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:120173:52
generatorResume#[native code]
asyncGeneratorStep#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21908:26
_next#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21927:29
tryCallOne#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26648:16
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26729:27
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27687:26
_callTimer#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27602:17
_callReactNativeMicrotasksPass#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27635:17
callReactNativeMicrotasks#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27799:44
__callReactNativeMicrotasks#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21006:46
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20806:45
__guard#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20986:15
flushedQueue#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20805:21
flushedQueue#[native code]
Expected behavior
This should both receive & send video and audio streams between the two clients

How to get the city location in react-native?

import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import * as Location from 'expo-location'
import Permissions from "expo-permissions";
export default function App() {
const [address, setAddress] = useState(null);
const [errorMsg, setErrorMsg] = useState(null);
useEffect(() => {
console.log(errorMsg)
console.log(address)
}, []);
const _getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== "granted") {
setErrorMsg = "Permission to access location was denied";
}
const location = await Location.reverseGeocodeAsync({});
const address = await Location.reverseGeocodeAsync(location.coords);
address;
_getLocationAsync();
};
let text = "Waiting...";
if (errorMsg) {
text = setErrorMsg;
} else if (address) {
text = setAddress[0].city;
}
return (
<View style={styles.container}>
<Text style={styles.text}>{text}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#bcbcbc',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 20
}
});
I have this code to get the city location in react-native, but I don't know what else I should do to get the location. I'm trying this for a while but I'm changing so many things and don't know exactly what I did...
I'd appreciate if someone could help me a little here
I used Geolocation from '#react-native-comunity/geolocation' which returns latitude and longitude.
Geolocation.getCurrentPosition(async (info) => {
const location = await getLocation(
info.coords.latitude,
info.coords.longitude,
);
...
And used google maps api for geocoding
export const getLocation = async (lat: number, long: number) => {
const apiKey = 'my api key'
return Api.get(
`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&key=${apiKey}`,
);
};
Hope this works for you

React native Printer

I'm new to react-native, I'm making app which can connect to printer with bluetooth I'm using react-native-ble-plx . I had successfully connect to my printer with bluetooth but I don't know to to print some thing from it.
import React, {PureComponent} from 'react';
import {View, Text, Button} from 'react-native';
import {BleManager} from 'react-native-ble-plx';
export default class App extends PureComponent {
constructor(props) {
super(props);
this.state = {};
this.manager = new BleManager();
}
componentDidMount() {
const subscription = this.manager.onStateChange(state => {
if (state === 'PoweredOn') {
console.log(state);
this.scanAndConnect();
}
}, true);
}
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
// Handle error (scanning will be stopped automatically)
console.log(error);
}
// if (device) {
// console.log(device);
// }
if (device.name === 'POSTEK061F') {
// Stop scanning as it's not necessary if you are scanning for one device.
this.manager.stopDeviceScan();
device
.connect()
.then(device => {
return device.discoverAllServicesAndCharacteristics();
})
.then(device => {
// Do work on device with services and characteristics
console.log(device.name);
console.log(device);
})
.catch(error => {
// Handle errors
});
// Proceed with connection.
}
});
}
async printHTML() {
//print something
}
render() {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Button onPress={this.printHTML} title="Print HTML" />
</View>
);
}
}
when user click on print button it should print some thing.

Connecting graphql query response with react-redux, getting ReferenceError: Can't find variable

I am working on a react-native app with graphql using apollo and react-redux.
I have the following graphql query that returns the following info for logged in user (using JTW token):
I am trying to run the above query and get the response into the react-native app via redux.
here's my graphql/queries/me.js
import { gql } from 'react-apollo';
export default gql`
{
me {
avatar
username
firstName
lastName
}
}
`;
I am trying to use it on my HomeScreen that user is dispatched to after successful login like this:
// ...
import { graphql, compose, withApollo } from 'react-apollo';
import { connect } from 'react-redux';
import ME_QUERY from '../graphql/queries/me';
class HomeScreen extends Component {
componentDidMount() {
this._getUserInfo();
}
_getUserInfo = async () => {
const { data: { me } } = await this.props.client.query({ query: ME_QUERY });
this.props.getUserInfo(me);
};
render () {
const { data } = this.props;
if (data.loading) {
return (
<Root>
<ActivityIndicator size="large" />
</Root>
);
}
return (
// snipped
);
};
}
export default withApollo(compose(
connect(undefined, { getUserInfo }),
graphql(GET_TWEETS_QUERY)
)(HomeScreen));
and here's my actions/user.js (redux action)
// ...
export function getUserInfo() {
return {
type: 'GET_USER_INFO',
info
}
}
and my reducer for user:
export default (state = initialState, action) => {
switch (action.type) {
// ...
case 'GET_USER_INFO':
return {
...state,
info: action.info
};
default:
return state;
}
};
Once the getUserInfo query ran and we got the info, I am trying to use it on a component called HeaderAvatar like this:
import React, { Component } from 'react';
import styled from 'styled-components/native';
import Touchable from '#appandflow/touchable';
import { connect } from 'react-redux';
const AVATAR_SIZE = 30;
const AVATAR_RADIUS = AVATAR_SIZE / 2;
const Avatar = styled.Image`
height: ${AVATAR_SIZE};
width: ${AVATAR_SIZE};
borderRadius: ${AVATAR_RADIUS};
`;
const Button = styled(Touchable).attrs({
feedback: 'opacity',
hitSlop: { top: 20, bottom: 20, right: 20, left: 20 }
})`
marginLeft: 15;
justifyContent: center;
alignItems: center;
`;
class HeaderAvatar extends Component {
state = { }
render () {
if (!this.props.info) {
// snipped
}
return (
<Button>
<Avatar source={{ uri: this.props.info.avatar }} />
</Button>
);
}
}
export default connect(state => ({ info: state.user.info }))(HeaderAvatar);
Any idea why I am not able to get the info field from the state object?
I know the query is executing and I am loading the info, I verified it by doing a console.log of me object inside the _getUserInfo() function and I can see the data.
P.S. sorry about the long post, I don't know how else to describe the problem.
This is how the error appears in the Android simulator: http://i.imgur.com/VdT2TJq.png
You're seeing that error because you're using an undeclared variable inside your action creator:
export function getUserInfo() {
return {
type: 'GET_USER_INFO',
info
}
}
You just need to add info to the arguments taken by getUserInfo.

React native signed APK crash

Signed APK crash after launch, in logCat i got requiring unknown module 'React'
Debug application works fine, but in logCat i got >> Requiring module 'React' by name is only supported for debugging purposes and will BREAK IN PRODUCTION!
React v15.4.1, React native v0.39.2 ?
Sorry for my english
this is my index.android.js
import React from 'react';
import {AppRegistry} from 'react-native';
import myapp from './index_start.js';
AppRegistry.registerComponent('myapp', () => myapp);
and index_start.js
import React, { Component } from "react";
import {
StyleSheet,
AppRegistry,
Text,
Image,
View,
AsyncStorage,
NetInfo,
StatusBar,
Navigator,
Dimensions
} from 'react-native';
// Window dismensions
const { width, height } = Dimensions.get('window');
// Device infos
import DeviceInfo from 'react-native-device-info';
// Native SplashScreen
import SplashScreen from 'react-native-splash-screen';
// Spinner
import Spinner from 'react-native-spinkit';
// Models
import User from './model/UserModel';
// Json data for initial launch
var DB = require('./DB.json');
// Components
import Stage from './components/stage/stage.js'
import Player from './components/player/player.js'
import Settings from './components/settings/settings.js'
import House from './stages/house/house.js'
// LocalStorage key
var USER_KEY = 'user_key';
const routes = [
{name: 'loading'},
{name: 'stage', component: Stage},
{name: 'house', component: House},
{name: 'settings', component: Settings}
];
const _navigator = null;
export default class myapp extends Component {
constructor(props) {
super(props);
this.state = {
isConnected: false,
isLoading: true,
_navigator: null,
stages: null
}
}
componentWillMount() {
// check if connected
this._checkConnexionType();
}
componentDidMount() {
SplashScreen.hide();
this._loadInitialData();
}
componentDidUpdate() {
// console.log(this.state.stages)
if (!this.state.isLoading && this.state.stages !== null) {
_navigator.push({
name: 'stage',
passProps: {
data: this.state.stages
}
})
}
}
/**
* Load localStorage Data
*/
async _loadInitialData() {
// GET User LocalStorage
if (this.state.stages == null) {
var localData;
//AsyncStorage.removeItem(USER_KEY)
AsyncStorage.getItem(USER_KEY).then((data) => {
if (data !== null) {
var localData = JSON.parse(data);
// User.uuid = localData.uuid;
User.setStages(localData.stages)
this.setState({
'stages' : localData.stages
})
} else {
var storage = {};
storage.setUiid = DeviceInfo.getUniqueID();
storage.stages = DB.stages;
AsyncStorage.setItem(USER_KEY, JSON.stringify(storage));
this.setState({
'stages' : DB.stages
})
}
})
}
if (this.state.isConnected) {
// var rStages = this._loadRemoteStages();
// console.log(rStages);
}
// Change state
setTimeout((function() {
this.setState({
'isLoading': false
})
}).bind(this), 1500);
}
/**
* GET stages from remote DB
*/
async _loadRemoteStages() {
await fetch(API_URL)
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson)
return responseJson;
})
.catch((error) => {
console.error(error);
});
}
/**
* CHECK IF user is connected to Network
* SET bool to state isLoading
*/
_checkConnexionType() {
NetInfo.isConnected.fetch().then(response => {
this.setState({ isConnected: response})
})
}
_renderScene(route, navigator) {
_navigator = navigator;
if (route.name == 'loading') {
return (
<View style={styles.container}>
<StatusBar hidden={true} />
<Image
style={{width: width, height: height}}
source={require('./img/screen.jpg')}
/>
<View style={styles.loading}>
<Text style={styles.loadingText}>CHARGEMENT</Text>
<Spinner type="ThreeBounce" color={'#fff'}/>
</View>
</View>
)
} else if (route.name == 'stage') {
return (
<Stage navigator={_navigator} {...route.passProps}/>
)
} else if (route.name == 'player') {
return (
<House navigator={_navigator} {...route.passProps}}/>
)
} else if (route.name == 'settings') {
return (
<Settings navigator={_navigator} {...route.passProps}/>
)
}
}
render() {
return (
<Navigator
initialRoute={{name: 'loading'}}
configureScene={() => Navigator.SceneConfigs.FloatFromBottomAndroid}
renderScene={this._renderScene.bind(this)}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
loading: {
flex: 1,
position: 'absolute',
bottom: 50,
left: 0,
right: 0,
alignItems: 'center',
},
loadingText:{
flex: 1,
fontFamily: 'CarterOne',
fontSize: 20,
color: '#fff'
}
});