I am running this basic react native code for fetching latitude and longitude value on both android device and emulator but nowhere is the current lat/long value is being returned.
When run on emulator some value is being returned but its not the correct lat/long value, whereas on device value isn't even being return.Here is the code
import React, { Component } from 'react'
import { View, Text, Switch, StyleSheet, Button} from 'react-native'
import { createStackNavigator } from 'react-navigation';
class HomeScreen extends Component {
render() {
return (
<View style = {styles.container}>
<Button
title="Add New Outlet"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
)
}
}
class DetailsScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: null,
longitude: null,
error: null,
};
}
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
render(){
return(
<View style = {styles.container}>
<Text style = {styles.boldText}>
Latitude:
</Text>
<Text>
{this.state.latitude}
</Text>
<Text style = {styles.boldText}>
Longitude:
</Text>
<Text>
{this.state.longitude}
</Text>
</View>
)
}
}
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
alignItems: 'center',
marginTop: 50
},
boldText: {
fontSize: 30,
color: 'red',
}
})
Please suggest any better alternatives..
For some reason navigator.geolocation is not working stable on Android devices, I changed getCurrentPosition to watchPosition and not used the third(geo_options) parameter. It worked for me.
componentDidMount() {
this.state.watchId = navigator.geolocation.watchPosition(
(position) => console.log(position),
(error) => console.log(error),
);
}
Also, you must clear watch and stop position observing when component unmounts.
componentWillUnmount() {
navigator.geolocation.clearWatch(this.state.watchId);
navigator.geolocation.stopObserving();
}
Fisrt, check android permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Next:
componentDidMount() {
if (Platform.OS === "android") {
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
).then(granted => {
if (granted) this._getCurrentLocation();
});
} else {
this._getCurrentLocation();
}
}
Then:
_getCurrentLocation = () => {
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
Related
I am building a ReactNative application for both IOS and Android platforms. My app needs to read data from another device via BLE communication. I am using this package for implementing BLE communication, https://github.com/innoveit/react-native-ble-manager. I am having a problem with receiving characteristic data on IOS even though it is working as expected on the Android platform.
I have added the following to the info.plist file:
Privacy - Bluetooth Always Usage Description: App needs to use Bluetooth to receive data from WaterRower machine
I have a component that scan and list down the BLE devices as follow. It is called, BleDeviceList.js
import React, {
useState,
useEffect,
} from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
NativeModules,
NativeEventEmitter,
Button,
Platform,
PermissionsAndroid,
FlatList,
TouchableHighlight,
} from 'react-native';
import {
Colors,
} from 'react-native/Libraries/NewAppScreen';
import BleManager from 'react-native-ble-manager';
const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);
const BleDeviceList = (props) => {
const [isScanning, setIsScanning] = useState(false);
const peripherals = new Map();
const [list, setList] = useState([]);
const [ connectedDevices, setConnectedDevices ] = useState([ ]);
const [ permissionsAllowed, setPermissionsAllowed ] = useState(false)
const startScan = () => {
if (!isScanning) {
BleManager.scan([], 3, true).then((results) => {
console.log('Scanning...');
setIsScanning(true);
}).catch(err => {
console.error(err);
});
}
}
const handleStopScan = () => {
console.log('Scan is stopped');
setIsScanning(false);
}
const handleDisconnectedPeripheral = (data) => {
let peripheral = peripherals.get(data.peripheral);
if (peripheral) {
peripheral.connected = false;
peripherals.set(peripheral.id, peripheral);
setList(Array.from(peripherals.values()));
}
console.log('Disconnected from ' + data.peripheral);
}
const handleUpdateValueForCharacteristic = (data) => {
console.log('Received data from ' + data.peripheral + ' characteristic ' + data.characteristic, data.value);
}
const retrieveConnected = () => {
BleManager.getConnectedPeripherals([]).then((results) => {
if (results.length == 0) {
console.log('No connected peripherals')
}
console.log(results);
for (var i = 0; i < results.length; i++) {
var peripheral = results[i];
peripheral.connected = true;
peripherals.set(peripheral.id, peripheral);
setList(Array.from(peripherals.values()));
}
});
}
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 isConnected = (peripheral) => {
return connectedDevices.filter(cd => cd.id == peripheral.id).length > 0;
}
const toggleConnectPeripheral = (peripheral) => {
if (peripheral){
if (isConnected(peripheral)){
BleManager.disconnect(peripheral.id);
setConnectedDevices(connectedDevices.filter(cd => cd.id != peripheral.id))
}else{
BleManager.connect(peripheral.id).then(() => {
let tempConnnectedDevices = [ ...connectedDevices ]
tempConnnectedDevices.push(peripheral);
setConnectedDevices(tempConnnectedDevices);
props.navigation.push('BleRowingSession', { peripheral: peripheral });
let p = peripherals.get(peripheral.id);
if (p) {
p.connected = true;
peripherals.set(peripheral.id, p);
setList(Array.from(peripherals.values()));
props.navigation.push('BleDeviceServiceList', { peripheral: peripheral });
}
console.log('Connected to ' + peripheral.id);
}).catch((error) => {
console.log('Connection error', error);
});
}
}
}
useEffect(() => {
BleManager.start({showAlert: false});
bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral);
bleManagerEmitter.addListener('BleManagerStopScan', handleStopScan );
bleManagerEmitter.addListener('BleManagerDisconnectPeripheral', handleDisconnectedPeripheral );
bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', handleUpdateValueForCharacteristic );
if (Platform.OS === 'android' && Platform.Version >= 23) {
PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("Permission is OK");
setPermissionsAllowed(true);
} else {
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("User accept");
setPermissionsAllowed(true);
} else {
console.log("User refuse");
setPermissionsAllowed(false);
}
});
}
});
} else {
setPermissionsAllowed(true)
}
return (() => {
console.log('unmount');
bleManagerEmitter.removeListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral);
bleManagerEmitter.removeListener('BleManagerStopScan', handleStopScan );
bleManagerEmitter.removeListener('BleManagerDisconnectPeripheral', handleDisconnectedPeripheral );
bleManagerEmitter.removeListener('BleManagerDidUpdateValueForCharacteristic', handleUpdateValueForCharacteristic );
})
}, []);
const renderConnectButton = (item) => {
if (isConnected(item)) {
return null
}
return (
<Button
title="Connect"
onPress={() => {
toggleConnectPeripheral(item)
}}
/>
)
}
const renderDisconnectButton = (item) => {
if (! isConnected(item)) {
return null
}
return (
<Button
title="Disconnect"
onPress={() => {
toggleConnectPeripheral(item)
}}
/>
)
}
const renderItem = (item) => {
const color = item.connected ? 'green' : '#fff';
return (
<TouchableHighlight>
<View style={[styles.row, {backgroundColor: color}]}>
<Text style={{fontSize: 12, textAlign: 'center', color: '#333333', padding: 10}}>{item.name}</Text>
<Text style={{fontSize: 10, textAlign: 'center', color: '#333333', padding: 2}}>RSSI: {item.rssi}</Text>
<Text style={{fontSize: 8, textAlign: 'center', color: '#333333', padding: 2, paddingBottom: 20}}>{item.id}</Text>
{renderConnectButton(item)}
{renderDisconnectButton(item)}
</View>
</TouchableHighlight>
);
}
const renderContent = () => {
if (! permissionsAllowed) {
return <Text>Bluetooth and locations permissions are required.</Text>
}
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
{global.HermesInternal == null ? null : (
<View style={styles.engine}>
<Text style={styles.footer}>Engine: Hermes</Text>
</View>
)}
<View style={styles.body}>
<View style={{margin: 10}}>
<Button
title={'Scan Bluetooth (' + (isScanning ? 'on' : 'off') + ')'}
onPress={() => startScan() }
/>
</View>
<View style={{margin: 10}}>
<Button title="Retrieve connected peripherals" onPress={() => retrieveConnected() } />
</View>
{(list.length == 0) &&
<View style={{flex:1, margin: 20}}>
<Text style={{textAlign: 'center'}}>No peripherals</Text>
</View>
}
</View>
</ScrollView>
<FlatList
data={list}
renderItem={({ item }) => renderItem(item) }
keyExtractor={item => item.id}
/>
</SafeAreaView>
</>
)
}
return (
renderContent()
);
};
const styles = StyleSheet.create({
scrollView: {
backgroundColor: Colors.lighter,
},
engine: {
position: 'absolute',
right: 0,
},
body: {
backgroundColor: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.dark,
},
highlight: {
fontWeight: '700',
},
footer: {
color: Colors.dark,
fontSize: 12,
fontWeight: '600',
padding: 4,
paddingRight: 12,
textAlign: 'right',
},
});
export default BleDeviceList;
As you can see in the code, when the Connect button is clicked, it will redirect the user to another component that reads data from another device. The following is the BleRowingSession.js that reads the data from another device.
import React, { useEffect, useState } from 'react';
import { Text, View, StyleSheet, NativeModules, NativeEventEmitter, ScrollView } from 'react-native';
import BleManager from 'react-native-ble-manager';
const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);
const serviceId = "00001826-0000-1000-8000-00805F9B34FB";
const characteristicId = "00002AD1-0000-1000-8000-00805F9B34FB";
let readDataCache = "";
const BleRowingSession = (props) => {
let peripheral = props.route.params.peripheral;
const [ readData, setReadData ] = useState("");
const setUpBleNotification = () => {
BleManager.retrieveServices(peripheral.id).then((peripheralData) => {
console.log('Retrieved peripheral services', peripheralData);
setTimeout(() => {
BleManager.startNotification(peripheral.id, serviceId, characteristicId).then(() => {
console.log('Started notification on ' + peripheral.id);
bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', (data) => {
readDataCache = readDataCache + "\n" + data.value.toString()
setReadData(readDataCache);
});
setTimeout(() => {
}, 500);
}).catch((error) => {
console.log('Notification error', error);
});
}, 500)
});
}
useEffect(() => {
setUpBleNotification()
}, [ ])
return (
<View style={styles.container}>
<ScrollView>
<Text>Ble Rowing Session</Text>
<Text>{readData}</Text>
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
})
export default BleRowingSession;
For now, the service id and characteristic id are hardcoded. Of course, I had to choose the right device on the first page that displays the list of BLE devices.
When I run the code, it is working as expected on the Android device, it is receiving the characteristic value. When I run the code on the actual IOS device, it is not receiving any data. But it can scan the devices and connect to them. What is wrong with my code and how can I fix it?
I'm setting up a page where I can Id with a Google account. This is my code:
import React from "react"
import { StyleSheet, Text, View, Image, Button } from "react-native"
import * as Google from "expo-google-app-auth";
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
signedIn: false,
name: "",
photoUrl: ""
}
}
signIn = async () => {
try {
const result = await Google.logInAsync({
androidClientId:
"1051966217196.apps.googleusercontent.com",
iosClientId:
"1051966217196.apps.googleusercontent.com",
scopes: ["profile", "email"]
})
if (result.type === "success") {
this.setState({
signedIn: true,
name: result.user.name,
photoUrl: result.user.photoUrl
})
} else {
console.log("cancelled")
}
} catch (e) {
console.log("error", e)
}
}
render() {
return (
<View style={styles.container}>
{this.state.signedIn ? (
<LoggedInPage name={this.state.name} photoUrl={this.state.photoUrl} />
) : (
<LoginPage signIn={this.signIn} />
)}
</View>
)
}
}
const LoginPage = props => {
return (
<View>
<Text style={styles.header}>Sign In With Google</Text>
<Button title="Sign in with Google" onPress={() => props.signIn()} />
</View>
)
}
const LoggedInPage = props => {
return (
<View style={styles.container}>
<Text style={styles.header}>Welcome:{props.name}</Text>
<Image style={styles.image} source={{ uri: props.photoUrl }} />
</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
}
})
On Android it's ok, everything is fine but in IOS I have that mistake :
Google 400 - That's an error - Error : redirect_uri_mismatch
Where is it goes wrong? I'm new to react native so I need detailed explanations.
I changed the bundle identifier to host.exp.exponent in Google credentials and it works. It's weird because I didn't change it in app.json. But it works.
I'm building a react native app using the react-native-maps dependency but am unable to navigate to other screens using react-navigator onPress from within the MapView.
I would like to pass the { communityId: ${community._id} } object to view the unique community screen.
code:
import React, { Component } from 'react';
import { View, Image, StyleSheet, Vibration, TouchableOpacity, Text } from 'react-native';
import MapView, { Callout } from 'react-native-maps';
import { Marker } from 'react-native-maps';
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require("./logo.png")}
style={{ width: 60, height: 30 }}
/>
);
}
}
class MapScreen extends Component {
constructor(props) {
super(props);
this.state = {
latitude: null,
longitude: null,
error: null,
communities: ""
};
}
componentDidMount() {
fetch("http://localhost:4000/community")
.then(res => res.json())
.then(res => {
this.setState({ communities: res });
});
Vibration.vibrate();
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
static navigationOptions = {
headerTitle: <LogoTitle />
};
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
render() {
const LatLng = {
latitude: this.state.latitude,
longitude: this.state.longitude
}
let commcoords;
this.state.communities &&
(commcoords = this.state.communities.map((community, id) => {
let commlatlong;
commlatlong = {
latitude: community.location.lat,
longitude: community.location.long
};
return (
<Marker
key={id}
coordinate={commlatlong}
title={community.name}>
<Callout>
<TouchableOpacity
onPress={() => this.navigateToView("Community", { communityId: `${community._id}` })}
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
)
}))
return (
<View style={styles.container}>
{this.state.latitude &&
<MapView
style={styles.map}
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.1011,
longitudeDelta: 0.1011,
}}>
<Marker
coordinate={LatLng}
title={`Latitude: ${this.state.latitude}`}
description={`Longitude: ${this.state.longitude}`}
pinColor='#000000'>
</Marker>
{commcoords}
</MapView>}
</View>
);
}
}
I have already attempted:
1) Using the normal navigation method.
onPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}
2) Using alternate touch methods, buttons, touchable highlights, etc.
3) Attempted to console.log the triggered touch method using the remote debugger. The console.log was never triggered in the console.
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
4) Researched and attempted solutions to no avail from the following stackoverflow links:
React Native - How to use React Navigation with React Native Maps?
React native maps click pin to take you to another screen
I would like to resolve this maps navigation issue to increase functionality in this native app. If there is an alternative method, I am open to any and all suggestions. Thank you.
I figured out how to trigger an the onpress event by using onCalloutPress in the Marker:
<Marker
key={id}
coordinate={commlatlong}
title={community.name}
onCalloutPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}>
<Callout>
<TouchableOpacity
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
I am now able to navigate to show screens from the map. Thanks to this post:
Marker click event on react native maps not working in react ios
Additional source:
onCalloutPress Callback that is called when a callout is tapped by the user.
https://github.com/react-native-community/react-native-maps/blob/master/docs/mapview.md
I am receiving there error "Maximum Call Stack Size Exceeded". After adding a conditional to the navigation file in my code. The stack I am using is React-Native with Expo, Redux, GraphQL and my navigation library is react-navigation. I am working on iOS simulator. This is the code that breaks the
app:
//navigations.js
if (!this.props.user.isAuthenticated) {
return <AuthenticationScreen />;
}
and this is the entirety of the navigations.js
import React, { Component } from "react";
import {
addNavigationHelpers,
StackNavigator,
TabNavigator
} from "react-navigation";
import { connect } from "react-redux";
import { FontAwesome } from "#expo/vector-icons";
import HomeScreen from "./screens/HomeScreen";
import ExploreScreen from "./screens/ExploreScreen";
import FavoritesScreen from "./screens/FavoritesScreen";
import ProfileScreen from "./screens/ProfileScreen";
import AuthenticationScreen from "./screens/AuthenticationScreen";
import { colors } from "./utils/constants";
const TAB_ICON_SIZE = 20;
const Tabs = TabNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: () => ({
headerTitle: "Saga",
tabBarIcon: ({ tintColor }) => (
<FontAwesome size={TAB_ICON_SIZE} color={tintColor} name="home" />
)
})
},
Explore: {
screen: ExploreScreen,
navigationOptions: () => ({
headerTitle: "Explore",
tabBarIcon: ({ tintColor }) => (
<FontAwesome size={TAB_ICON_SIZE} color={tintColor} name="search" />
)
})
},
Favorites: {
screen: FavoritesScreen,
navigationOptions: () => ({
headerTitle: "Favorites",
tabBarIcon: ({ tintColor }) => (
<FontAwesome
size={TAB_ICON_SIZE}
color={tintColor}
name="file-video-o"
/>
)
})
},
Profile: {
screen: ProfileScreen,
navigationOptions: () => ({
headerTitle: "Profile",
tabBarIcon: ({ tintColor }) => (
<FontAwesome size={TAB_ICON_SIZE} color={tintColor} name="user" />
)
})
}
},
{
lazy: true,
tabBarPosition: "bottom",
swipeEnabled: false,
tabBarOptions: {
showIcon: true,
showLabel: false,
activeTintColor: colors.PRIMARY,
inactiveTintColor: colors.LIGHT_GRAY,
style: {
backgroundColor: colors.BASE_GRAY,
height: 50,
paddingVertical: 5
}
}
}
);
const AppMainNav = StackNavigator(
{
Home: {
screen: Tabs
}
},
{
cardStyle: {
backgroundColor: "#F1F6FA"
},
navigationOptions: () => ({
headerStyle: {
backgroundColor: colors.BASE_GRAY
},
headerTitleStyle: {
fontWeight: "bold",
fontSize: 24,
color: colors.BLUE
}
})
}
);
class AppNavigator extends Component {
render() {
const nav = addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav
});
if (!this.props.user.isAuthenticated) {
return <AuthenticationScreen />;
}
return <AppMainNav navigation={nav} />;
}
}
export default connect(state => ({
nav: state.nav,
user: state.user
}))(AppNavigator);
export const router = AppMainNav.router;
For good measure this is the user.js reducer:
const initialState = {
token: null,
isAuthenticated: false,
info: null
};
export default (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
I can't see what would be causing an infinite loop.
Update #1
AuthenticationScreen.js (Minus Imports)
const Root = styled.View``;
const T = styled.Text``;
class AuthenticationScreen extends Component {
state = {};
render() {
return (
<Root>
<T>AuthenticationScreen</T>
</Root>
);
}
}
export default AuthenticationScreen;
As I understand it, you've isolated the problem to this code...
if (!this.props.user.isAuthenticated) {
return <AuthenticationScreen />;
}
return <AppMainNav navigation={nav} />;
And if you remove...
if (!this.props.user.isAuthenticated) {
return <AuthenticationScreen />;
}
it works fine, which means <AppMainNav> must be fine. So the infinite loop must be in your <AuthenticationScreen /> code.
I am trying to get the longitude and langtitude but it seems like I can't access it from the default geolocation json object that I get.
I followed this example form the docs and it works great but I only need the long & lat so I am trying to pick it out like this:
const LATITUDE = 19.0760;
const LONGITUDE = 72.8777;
class Map extends Component {
state = {
region: {
latitude: LATITUDE,
longitude: LONGITUDE
},
};
watchID: ?number = null;
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({
initialRegion: {
latitude: initialPosition.coords.latitude,
longitude: initialPosition.coords.longitude,
}
});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
var lastPosition = JSON.stringify(position);
this.setState({
lastRegion: {
latitude: lastPosition.coords.latitude,
longitude: lastPosition.coords.longitude,
}
});
});
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
render() {
return (
<View>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialRegion}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastRegion}
</Text>
</View>
);
}
}
Eventualy I want to do render something like this:
render() {
return (
<MapView
style={ styles.map }
initialRegion={{
latitude: {this.state.lat},
longitude:{this.state.long},
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
}
Try this:
import React, { Component } from 'react';
import {
MapView,
StyleSheet,
View,
} from 'react-native';
var Dimensions = require('Dimensions'),
windowSize = Dimensions.get('window'),
Screen = require('Dimensions').get('window'),
NavigationBar = require('react-native-navbar');
var regionText = {
latitude: '0',
longitude: '0',
latitudeDelta: '0',
longitudeDelta: '0',
};
class LocateMap extends Component {
createAnnotation(longitude, latitude) {
return {
longitude,
latitude,
draggable: true,
onDragStateChange: (event) => {
if (event.state === 'starting') {
this.setState({
annotations: [this.createAnnotation(event.longitude, event.latitude)],
});
}
},
};
}
constructor(props) {
super(props);
this.state = {
isFirstLoad: true,
annotations: [],
mapRegion: undefined,
};
}
render() {
if (this.state.isFirstLoad) {
var onRegionChangeComplete = (region) => {
//When the MapView loads for the first time, we can create the annotation at the
//region that was loaded.
this.setState({
isFirstLoad: true,
annotations: [this.createAnnotation(region.longitude, region.latitude)],
});
};
}
const rightButtonConfig = {
title: 'Locate',
tintColor:'#ffffff',
handler: () => {
this.props.data.getMapPosition(this.state.annotations[0].longitude, this.state.annotations[0].latitude);
this.props.navigator.pop();
},
};
return (
<View style={{flex:1}}>
<MapView
style={styles.map}
onRegionChangeComplete={onRegionChangeComplete}
region={this.state.mapRegion}
annotations={this.state.annotations}
zoomEnabled={true}
showsUserLocation={true}
/>
</View>
);
}
};
var styles = StyleSheet.create({
map: {
height: Screen.height,
width: Screen.width
}
});
module.exports= LocateMap;