i'm using React native AsyncStroare with written on firebase when device connected with internet
but i am facing unknown problem which hang up my application which doesn't allow even click event
Anyone has ever faced this kind of problem ever?
i'm sharing code,
import React, { Component, PropTypes } from 'react';
import { StyleSheet, View, Text, Dimensions, AppRegistry, TouchableOpacity, Animated, Button, Alert, Vibration, AsyncStorage, NetInfo} from 'react-native';
import BackgroundGeolocation from 'react-native-mauron85-background-geolocation';
import MapView, { MAP_TYPES } from 'react-native-maps';
import * as firebase from "firebase";
const onStartPress = () => {
BackgroundGeolocation.start(
function (locations) {
Alert.alert('Tracking has been started');
Vibration.vibrate();
}
);
};
const onStopPress = () => {
BackgroundGeolocation.stop(
function (locations) {
Alert.alert('Tracking has been stop');
Vibration.vibrate();
}
);
};
// Initialize Firebase
const firebaseConfig = {
apiKey: "xxxx",
authDomain: "first-project-910a2.firebaseapp.com",
databaseURL: "https://first-project-910a2.firebaseio.com",
storageBucket: "gs://first-project-910a2.appspot.com",
};
const firebaseApp = firebase.initializeApp(firebaseConfig);
const rootRef = firebase.database().ref();
const itemsRef = rootRef.child('gps');
const email = "test#email.com";
const password = "test121";
var uid = 0;
var currentDistance = 0;
var eventOccur = 0;
firebaseApp.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
console.log( errorCode + ": "+ errorMessage );
});
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
uid = JSON.stringify(user.uid);
} else {
uid = 0;
}
});
var SchoolJS = require('./SchoolJS.js');
const { width, height } = Dimensions.get('window');
const ASPECT_RATIO = width / height;
const LATITUDE = 23.0123937;
const LONGITUDE = 72.5227731;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
let id = 0;
let arb = 0.01;
let busGpsCoordinates = [];
let prevlatOffline = 0;
let prevlongOffline = 0;
export default class MyScene extends Component {
constructor(props) {
super(props);
this.state = {
region: {
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
},
};
}
componentWillMount() {
BackgroundGeolocation.configure({
desiredAccuracy: 10,
stationaryRadius: 50,
distanceFilter: 50,
locationTimeout: 30,
notificationTitle: 'Background tracking',
notificationText: 'enabled',
debug: false,
startOnBoot: false,
stopOnTerminate: false,
locationProvider: BackgroundGeolocation.provider.ANDROID_ACTIVITY_PROVIDER,
interval: 5000,
fastestInterval: 2000,
activitiesInterval: 5000,
stopOnStillActivity: false,
});
BackgroundGeolocation.on('location', (location) => {
// since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
var myConnectionsRef = firebase.database().ref('users/'+uid+'/connections');
// stores the timestamp of my last disconnect (the last time I was seen online)
var lastOnlineRef = firebase.database().ref('users/'+uid+'/lastOnline');
var connectedRef = firebase.database().ref('.info/connected');
connectedRef.on('value', function(snap) {
if (snap.val() === true) {
// We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
// add this device to my connections list
// this value could contain info about the device or a timestamp too
var con = myConnectionsRef.push(true);
// when I disconnect, remove this device
con.onDisconnect().remove();
// when I disconnect, update the last time I was seen online
lastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);
//sync with firebase when reconnect
/*BackgroundGeolocation.start(() => {
console.log('[DEBUG] BackgroundGeolocation start successfully');
});*/
AsyncStorage.getItem(uid+"offline").then((value) => {
busGpsJsonObj = JSON.parse(value);
console.log("BUS OBJ : " + busGpsJsonObj);
if(busGpsJsonObj != null){
busGpsJsonObj.forEach(function(locationObj) {
newPostKey = firebase.database().ref().child('gps').push().key;
todaydate = SchoolJS.today();
newPostKey = (newPostKey != "") ? "/"+todaydate+"/"+newPostKey : "";
firebaseApp.database().ref('gps/' + uid+newPostKey).set({
speed : locationObj.speed,
accuracy: locationObj.accuracy,
bearing: locationObj.bearing,
longitude: locationObj.longitude,
altitude: locationObj.altitude,
latitude: locationObj.latitude,
time: locationObj.time,
locationProvider: locationObj.locationProvider,
});
});
AsyncStorage.removeItem(uid+"offline");
busGpsCoordinates = [];
}
}).done();
}
});
//handle your locations here
timekey = JSON.stringify(location.time);
speed = JSON.stringify(location.speed),
accuracy = JSON.stringify(location.accuracy),
bearing = JSON.stringify(location.bearing),
longitude = JSON.stringify(location.longitude),
altitude = JSON.stringify(location.altitude),
latitude = JSON.stringify(location.latitude),
time = JSON.stringify(location.time),
locationProvider = JSON.stringify(location.locationProvider),
timekey = timekey.toString();
newPostKey = firebase.database().ref().child('gps').push().key;
todaydate = SchoolJS.today();
newPostKey = (newPostKey != "") ? "/"+todaydate+"/"+newPostKey : "";
latitude = latitude.replace(/^"(.*)"$/, '$1');
longitude = longitude.replace(/^"(.*)"$/, '$1');
NetInfo.isConnected.fetch().then(isConnected => {
if(!isConnected)
{
if(busGpsCoordinates.length == 0)
{
busGpsCoordinates.push({
speed : speed,
accuracy: accuracy,
bearing: bearing,
longitude: longitude,
altitude: altitude,
latitude: latitude,
time: time,
locationProvider: locationProvider,
});
AsyncStorage.setItem(uid+"offline", JSON.stringify(busGpsCoordinates ) );
}
else
{
prevData = JSON.stringify(busGpsCoordinates[busGpsCoordinates.length - 1] );
prevData = JSON.parse(prevData);
currentDistance = SchoolJS.distance(prevData.latitude,prevData.longitude,latitude,longitude);
if(currentDistance > 30)
{
busGpsCoordinates.push({
speed : speed,
accuracy: accuracy,
bearing: bearing,
longitude: longitude,
altitude: altitude,
latitude: latitude,
time: time,
locationProvider: locationProvider,
});
AsyncStorage.setItem(uid+"offline", JSON.stringify(busGpsCoordinates ) );
}
}
}
});
this.animateRandom(parseFloat(latitude),parseFloat(longitude));
// retrieve the last record from `ref`
if(uid != 0)
{
itemsRef.once("value", function(snapshot) {
var totalChild = snapshot.child(uid).child(todaydate).numChildren();
if(totalChild == 0)
{
firebaseApp.database().ref('gps/' + uid+newPostKey).set({
speed : speed,
accuracy: accuracy,
bearing: bearing,
longitude: longitude,
altitude: altitude,
latitude: latitude,
time: time,
locationProvider: locationProvider,
});
}
});
itemsRef.child(uid).child(todaydate).limitToLast(1).on('child_added', function(snapshot) {
previousLatitude = JSON.stringify(snapshot.val().latitude);
previousLongitude = JSON.stringify(snapshot.val().longitude);
previousLatitude = previousLatitude.replace(/^"(.*)"$/, '$1');
previousLongitude = previousLongitude.replace(/^"(.*)"$/, '$1');
latitude = latitude.replace(/^"(.*)"$/, '$1');
longitude = longitude.replace(/^"(.*)"$/, '$1');
currentDistance = SchoolJS.distance(previousLatitude,previousLongitude,latitude,longitude);
eventOccur++;
if(currentDistance > 30)
{
firebaseApp.database().ref('gps/' + uid+newPostKey).set({
speed : speed,
accuracy: accuracy,
bearing: bearing,
longitude: longitude,
altitude: altitude,
latitude: latitude,
time: time,
locationProvider: locationProvider,
});
}
});
}
});
BackgroundGeolocation.on('stationary', (stationaryLocation) => {
//handle stationary locations here
console.log(JSON.stringify(stationaryLocation));
});
BackgroundGeolocation.on('error', (error) => {
console.log('[ERROR] BackgroundGeolocation error:', error);
});
BackgroundGeolocation.isLocationEnabled((success, fail) => {
if(success != 1 && fail == "undefined")
{
BackgroundGeolocation.stop(() => {
console.log('[DEBUG] BackgroundGeolocation stop successfully');
});
}
});
}
onRegionChange(region) {
this.setState({ region });
}
jumpRandom() {
this.setState({ region: this.randomRegion() });
}
animateRandom(newLatitude = LATITUDE ,newLongitude = LONGITUDE) {
this.map.animateToRegion(this.randomRegion(newLatitude, newLongitude));
}
randomRegion(newLatitude = LATITUDE ,newLongitude = LONGITUDE) {
const { region } = this.state;
return {
...this.state.region,
latitude: newLatitude,
longitude: newLongitude,
};
}
render() {
return (
<View style={styles.container}>
<MapView
showsUserLocation = { true }
provider={this.props.provider}
ref={ref => { this.map = ref; }}
mapType={MAP_TYPES.TERRAIN}
style={styles.map}
initialRegion={this.state.region}
onRegionChange={region => this.onRegionChange(region)}
>
<MapView.Marker.Animated
coordinate={this.state.region}
/>
</MapView>
<View style={styles.buttonContainer}>
<TouchableOpacity
onPress={onStartPress}
style={[styles.bubble, styles.button]}
>
<Text>Start</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={onStopPress}
style={[styles.bubble, styles.button]}
>
<Text>Stop</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
MyScene.propTypes = {
provider: MapView.ProviderPropType,
};
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
...StyleSheet.absoluteFillObject,
},
bubble: {
backgroundColor: 'rgba(255,255,255,0.7)',
paddingHorizontal: 18,
paddingVertical: 12,
borderRadius: 20,
},
latlng: {
width: 200,
alignItems: 'stretch',
},
button: {
width: 80,
paddingHorizontal: 12,
alignItems: 'center',
marginHorizontal: 10,
},
buttonContainer: {
flexDirection: 'row',
marginVertical: 20,
backgroundColor: 'transparent',
},
});
anyone can help me out from this problem.
Related
I am trying to get navigation directions using mapbox-sdk for react-native from npm package:
"#mapbox/mapbox-sdk": "^0.11.0"
And for rendering the directions returned by mapbox-sdk I am using the below npm package:
"#react-native-mapbox-gl/maps": "^8.1.0-rc.8",
Code I am using for retrieving directions:
import MapboxGL from '#react-native-mapbox-gl/maps'
// Mapbox SDK related package
import MapboxDirectionsFactory from '#mapbox/mapbox-sdk/services/directions'
import { lineString as makeLineString } from '#turf/helpers'
import GeoLocationService from '../../services/geolocation/GeoLocationService';
import GeoLocationCore from '#react-native-community/geolocation'
const accessToken = "ACESS_TOKEN_FROM_MAPBOX_API_DASHBOARD"
const directionsClient = MapboxDirectionsFactory({accessToken})
constructor(props) {
super(props);
this.state = {
longitude: 0,
latitude: 0,
orderLongitude: 0,
orderLatitude: 0,
route: null,
};
}
async componentDidMount() {
const {route} = this.props
// Lets say route.params contains the below object:
// { "longitude": "33.981982", "latitude": "-6.851599"}
console.log("Params from other screen: ", route.params)
MapboxGL.setAccessToken(accessToken)
MapboxGL.setConnected(true);
MapboxGL.setTelemetryEnabled(true);
const permission = await MapboxGL.requestAndroidLocationPermissions();
let latitude, longitude;
if(Platform.OS == "android") {
GeoLocationService.requestLocationPermission().then(() => {
GeoLocationCore.getCurrentPosition(
info => {
const { coords } = info
latitude = coords.latitude
longitude = coords.longitude
//this.setState({longitude: coords.longitude, latitude: coords.latitude})
this.setState({longitude: -6.873795, latitude: 33.990777, orderLongitude: route.params.longitude, orderLatitude: route.params.latitude})
console.log("your lon: ", longitude)
console.log("your lat", latitude)
this.getDirections([-6.873795, 33.990777], [route.params.longitude, route.params.latitude])
},
error => console.log(error),
{
enableHighAccuracy: false,
//timeout: 2000,
maximumAge: 3600000
}
)
})
}
}
getDirections = async (startLoc, destLoc) => {
const reqOptions = {
waypoints: [
{coordinates: startLoc},
{coordinates: destLoc},
],
profile: 'driving',
geometries: 'geojson',
};
const res = await directionsClient.getDirections(reqOptions).send()
//const route = makeLineString(res.body.routes[0].geometry.coordinates)
const route = makeLineString(res.body.routes[0].geometry.coordinates)
console.log("Route: ", JSON.stringify(route))
this.setState({route: route})
}
Code I am using for rendering road directions fetched by mapbox-sdk:
renderRoadDirections = () => {
const { route } = this.state
return route ? (
<MapboxGL.ShapeSource id="routeSource" shape={route.geometry}>
<MapboxGL.LineLayer id="routeFill" aboveLayerID="customerAnnotation" style={{lineColor: "#ff8109", lineWidth: 3.2, lineCap: MapboxGL.LineJoin.Round, lineOpacity: 1.84}} />
</MapboxGL.ShapeSource>
) : null;
};
Code I am using for rendering map and directions:
render() {
return (
<View style={{ flex: 1 }}>
<MapboxGL.MapView
ref={(c) => this._map = c}
style={{flex: 1, zIndex: -10}}
styleURL={MapboxGL.StyleURL.Street}
zoomLevel={10}
showUserLocation={true}
userTrackingMode={1}
centerCoordinate={[this.state.longitude, this.state.latitude]}
logoEnabled={true}
>
{this.renderRoadDirections()}
<MapboxGL.Camera
zoomLevel={10}
centerCoordinate={[this.state.longitude, this.state.latitude]}
animationMode="flyTo"
animationDuration={1200}
/>
</MapboxGL.MapView>
</View>
)
}
Now when I try to render the GeoJson retreived the road directions line not showing on map, so I thought maybe something wrong with my GeoJson and tested it from here but it looks fine:
https://geojsonlint.com/
GeoJson that I tested and looks okay:
{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[-6.880611,33.9916],[-6.882194,33.990166],[-6.882439,33.99015],[-6.882492,33.990028],[-6.882405,33.98991],[-6.878006,33.990299],[-6.87153,33.990978],[-6.871386,33.990925],[-6.871235,33.991016],[-6.869793,33.991165],[-6.870523,33.990292]]}}
Example of what I am trying to achieve:
What could be wrong in my code that makes road directions line not showing on map?
Found what was causing the <LineLayer/> not showing on map, removing the the attribute aboveLayerID from the following line:
<MapboxGL.LineLayer id="routeFill" aboveLayerID="customerAnnotation" style={{lineColor: "#ff8109", lineWidth: 3.2, lineCap: MapboxGL.LineJoin.Round, lineOpacity: 1.84}} />
So it becomes:
<MapboxGL.LineLayer id="routeFill" style={{lineColor: "#ff8109", lineWidth: 3.2, lineCap: MapboxGL.LineJoin.Round, lineOpacity: 1.84}} />
Result:
I've added MapView into my app but i want to initialize the region with the current user's live location, The code on the emulator changes the initial region to the location of google's HQ in CA (I know that's normal and i can change the emulator's location in settings) but on my own phone, the initial region doesn't change at all.
using the GEO location api preferred by react native:
const [region, setRegion] = useState({
latitude: -1.951670,
longitude: 30.157518,
latitudeDelta: 0.015,
longitudeDelta: 0.015,
})
useEffect(() => {
let currentLocation = true;
let newRegion = { latitude: null, longitude: null, latitudeDelta: null, longitudeDelta: null };
newRegion.longitudeDelta = region.longitudeDelta;
newRegion.latitudeDelta = region.latitudeDelta;
Geolocation.getCurrentPosition((info) => {
newRegion.latitude = info.coords.latitude
newRegion.longitude = info.coords.longitude;
},
(error) => {
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
)
//To make sure no null is still present in the newReion obj
for (var key in newRegion) {
if (!newRegion[key]) {
currentLocation = false;
break;
}
}
if (currentLocation) {
setRegion(newRegion);
}
}, [])
//Map view implementation:
<MapView
provider={PROVIDER_GOOGLE}
ref={map => _map = map}
showsUserLocation={true}
style={styles.map}
initialRegion={initialPosition}
onRegionChangeComplete={(region) => setInitialPosition(region)}
/>
I have created an android app with CRNA, I can get the current location of the user by Expo's location API. But I can't figure out how to get the city name of a pinned location? This is my code so far:
class Map extends Component {
constructor(props) {
super(props);
this.state = {
region: {
latitude: 41.0141977,
longitude: 28.9638121,
latitudeDelta: 0.1,
longitudeDelta: 0.05,
},
x: {
latitude: 41.0238343,
longitude: 29.0335236,
},
regionName: "",
}
}
onDragEnd(e) {
this.setState({x: e.nativeEvent.coordinate});
}
onRegionChange(region) {
this.setState({region});
}
render() {
return (
<Modal
animationType={"slide"}
transparent={true}
visible={this.props.visible}
onRequestClose={this.props.changeState}
style={styles.modal}
>
<MapView
region={this.state.region}
onRegionChange={this.onRegionChange.bind(this)}
style={styles.map}
><MapView.Marker draggable
coordinate={this.state.x}
onDragEnd={this.onDragEnd.bind(this)}
/></MapView>
</Modal>
);
}
}
For that you need to use some for of geocoding.
In general look at the google maps page about geocoding.
And here is an npm package for react native.
As I googled more and more I learnt it's called reverse geocoding. So I created an redux action like this and it solved my problem very well:
export function fetchCityName(lat, lng) {
const link = `http://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}`;
return dispatch => {
dispatch(startFetch());
return fetch(link)
.then(response => response.json())
.then(responseJson => {
const addressComponent = _.get(responseJson, 'results[0].address_components', []);
const getAreaName = zone => _.get(
addressComponent,
`[${_.findIndex(addressComponent, obj => _.includes(obj.types, zone))}].long_name`
);
const region = ' ' + getAreaName('administrative_area_level_1');
const country = ' ' + getAreaName('country');
const region2 = getAreaName('administrative_area_level_2');
const location = region2 ?
[region2, region, country].toString() :
region.concat(',' + country);
dispatch(getCityName(location));
})
.catch(console.error)
I have a questionnaire application which works fine on Android. However on iOS, the ListView never shows all the questions. Of the 11 questions in the questionnaire. only about 2 or 2.5 of them are rendered. A small amount of scrolling does seem to happen based on the size off the emulator window. I have tried all the suggestion posted including:
- setting the height of the ListView item using Dimensions
- setting flex:1 up the container hierarchy.
But nothing seems to work.
I am posting a much abridged and modified version of the code that uses NativeBase's RadionButton. My original code uses my own home-brewed radio buttons, but all of them have the same problem. I would appreciate any help I can get on this problem. Thanks in advance.
Here is my code:
import React, { Component } from 'react';
import {
Alert,
StyleSheet,
// Text,
TextInput,
View,
ListView,
TouchableHighlight,
Dimensions,
} from 'react-native';
import Svg,{
Rect,
} from 'react-native-svg';
import { Actions } from 'react-native-router-flux';
import realm from './realm';
import Utils from './Utils';
import moment from 'moment';
import { Container, Content, InputGroup, Input,
List, ListItem, Text, Radio } from 'native-base';
require('Dimensions');
const windowDims = Dimensions.get('window');
///////////////////////////////////////////////////////////////////////////////
const WhenSymptom = 0;
const FrequencySymptom = 1;
const FeelingSymptom = 2;
const YesNoSymptom = 3;
const ValueSymptom = 4;
global.junk = "hello";
var SymptomValues = new Array
(
// WhenSymptom
[ "none", "only after inactivity", "mostly AM", "AM and PM", "all the time" ],
// FrequencySymptom
[ "None", "Less than usual", "Usual", "More than usual", "Very bothersome" ],
// FeelingSymptom
[ "Great", "Fair", "So-so", "Poor", "Terrible" ],
// YesNoSymptom
[ "No", "", "", "", "Yes" ],
// ValueSymptom
[]
);
// var questions = new Array
global.questions = new Array
(
{ rowIndex: 0,
chartTitle: "Tremors",
answer: 0},
{ rowIndex: 1,
chartTitle: "Speech-slurring",
answer: 1},
{ rowIndex: 2,
chartTitle: "Feeling-stuck",
answer: 2},
{ rowIndex: 3,
chartTitle: "Instability",
answer: 3},
{ rowIndex: 4,
chartTitle: "Anxiety",
answer: 4},
{ rowIndex: 5,
chartTitle: "# of steps",
answer: 1},
{ rowIndex: 6,
chartTitle: "Pain or aches",
answer: 3},
{ rowIndex: 7,
chartTitle: "Day drowsiness",
answer: 2},
{ rowIndex: 8,
chartTitle: "Urinary urgency",
answer: 1},
{ rowIndex: 9,
chartTitle: "Constipation",
answer: 0},
{ rowIndex: 10,
chartTitle: "Overall feeling",
answer: 2}
);
var colors = new Array( "green", "#dbdb70", "yellow", "orange", "red" );
var styles = StyleSheet.create({
list: {
flexDirection: 'column',
flex:1,
//height: windowDims.height-30,
marginTop: 52,
},
questionText: {
flex:1,
fontSize: 14,
// color: 'white',
color: 'black',
alignSelf: 'flex-start'
},
});
var junk = 0;
// const mySaveAction = () => console.log('Back From the Questions page ');
///////////////////////////////////////////////////////////////////////////////
export default class QuestionsPage extends Component {
constructor(props){
super(props);
console.log("numToPop: " + this.props.numToPop);
var ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 != r2
//rowHasChanged: (r1, r2) => true
});
// if it is a new panel, set all the answers to -1
let answersIn = new Array(questions.length);
if (this.props.panel == null) {
for (let i in questions) {
answersIn[i] = -1;
questions[i].answer = -1;
}
}
else {
answersIn = this.props.panel.symptoms.split(",");
for (let i in questions) {
questions[i].answer = answersIn[i];
}
}
this.state = {
ds: questions,
dataSource:ds,
editAllowed: 0,
initialAnswers: answersIn,
behavior: 'position'
// there is three ways to adjust (position , height , padding )
}
}
///////////////////////////////////////////////////////////////////////////////
componentDidMount(){
this.setState({
dataSource:this.state.dataSource.cloneWithRows(this.state.ds),
});
// When we come in here with newPanel == 1, the route was
// MenuPage => QuestionsPage; so cancel should just be
// Actions.pop(). If newPanel == 0, , the route was
// MenuPage => Calendar => QuestionsPage; so cancel should call Actions.pop(2)
Actions.refresh({ onRight: () => { this._saveButtonPressed(); },
onBack: () => { this._cancelButtonPressed(); },
title: (this.props.panel == null ?
"New panel" :
(" Panel of " +
Utils.readableDate(this.props.panel.panelDate)))
});
}
///////////////////////////////////////////////////////////////////////////////
_saveButtonPressed() {
var finalAnswers = new Array(questions.length);
var panelChanged = 0;
var dateString;
for (let i=0; i<finalAnswers.length; i++) {
finalAnswers[i] = questions[i].answer;
if (finalAnswers[i] != this.state.initialAnswers[i])
panelChanged = 1;
}
var symptoms = "" + finalAnswers[0];
for (let i=1; i<finalAnswers.length; i++) {
symptoms = (symptoms + "," + finalAnswers[i]);
}
console.log("_saveButtonPressed panelChanged: " + panelChanged);
if (this.props.panel == null) {
if (panelChanged) {
let myPanelKey = Utils.newPanelKey();
this._updateDB(myPanelKey, symptoms);
}
Actions.pop();
}
else {
if (panelChanged) {
this._updateDB(this.props.panel.panelDate, symptoms);
}
// Kluge:
this._returnFromScreen();
}
}
///////////////////////////////////////////////////////////////////////////////
_updateDB(myPanelDate, symptoms) {
console.log("_updateDB dt: " + moment(myPanelDate).toString() +
" symptoms: " + symptoms);
// var dateString = Utils._myISOString(myPanelDate);
realm.write(() => {
realm.create('Symptoms', {panelDate: myPanelDate, symptoms: symptoms}, true);
});
console.log("Trace");
let after = realm.objects('Symptoms');
for (let i=0; i<after.length; i++) {
console.log("panelDate: " + moment(after[i].panelDate).toString() +
" (" + after[i].panelDate + " )" +
"; symptoms: " + after[i].symptoms);
}
}
///////////////////////////////////////////////////////////////////////////////
_returnFromScreen() {
if (this.props.numToPop == 1)
Actions.pop();
else
Actions.pop({popNum: 2});
}
///////////////////////////////////////////////////////////////////////////////
_cancelButtonPressed() {
console.log("_cancelButtonPressed in QuestionsPage numToPop: " +
this.props.numToPop);
this._returnFromScreen();
}
///////////////////////////////////////////////////////////////////////////////
_rowPressed(rowData){
console.log("In _rowPressed");
}
///////////////////////////////////////////////////////////////////////////////
_buttonPressed(rowIndex, value, forceEdit = 0){
// console.log("In _buttonPressed " + rowIndex + " " + value);
let newDs = this.state.ds.slice();
newDs[rowIndex] = {
...this.state.ds[rowIndex],
answer: value,
};
// This is absolutely essential to do!!!!!
questions[rowIndex].answer = value;
this.setState({
dataSource:this.state.dataSource.cloneWithRows(newDs),
})
// this.forceUpdate();
// console.log("answers: " + this.state.answers);
}
///////////////////////////////////////////////////////////////////////////////
_renderButton(rowIndex, column){
return (
<ListItem>
<Radio selected={this.state.ds[rowIndex].answer == column ? true : false} />
<Text>{SymptomValues[0][column]}</Text>
</ListItem>
);
}
///////////////////////////////////////////////////////////////////////////////
_renderRow(rowData){
// console.log("renderRow " + this.state.ds[rowData.rowIndex].answer);
return (
<View style={styles.list}>
<Text style={styles.questionText}>Question {rowData.rowIndex+1}.</Text>
<Container>
<Content>
<List>
{ this._renderButton(rowData.rowIndex, 0) }
{ this._renderButton(rowData.rowIndex, 1) }
{ this._renderButton(rowData.rowIndex, 2) }
{ this._renderButton(rowData.rowIndex, 3) }
{ this._renderButton(rowData.rowIndex, 4) }
</List>
</Content>
</Container>
</View>
);
}
///////////////////////////////////////////////////////////////////////////////
render(){
// console.log("render");
return (
<ListView style={styles.list}
dataSource = {this.state.dataSource}
renderRow = {this._renderRow.bind(this)}>
</ListView>
);
}
}
module.exports = QuestionsPage;
// Util.js
import moment from 'moment';
let Utils = {
// toISOString returns (YYYY-MM-DDTHH:mm:ss.sssZ
newPanelKey: function() {
let myPanelDate = moment();
myPanelDate.milliseconds(0);
myPanelDate.seconds(0);
myPanelDate.minutes(0);
return myPanelDate.valueOf();
},
readableDate: function(utc) {
return moment(utc).format("MMM D, YYYY#ha");
},
readableDateNoTime: function(utc) {
return moment(utc).format("MMM D, YYYY");
},
shortDate: function(utc) {
let mom = moment(utc);
let date = mom.format("DDMMM:hha");
return date.substring(0,date.length-1);
}
}
module.exports = Utils;
I can't get geolocations in the emulator or on a physical phone.
I'm using Titanium SDK 1.6.2, ADK 2.2.
I've followed the approaches used here to no avail.
What am I missing? Thanks in advance.
Error:
Says that e.coords is null when doing this assignment. f_lng = e.coords.longitude;
Code:
function get_geolocation() {
try {
Ti.Geolocation.preferredProvider = 'gps';
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = 10;
if( Titanium.Geolocation.locationServicesEnabled === false ) {
throw('Your device has GPS turned off. Please turn it on.');
}
var f_lat, f_lng;
Titanium.Geolocation.getCurrentPosition(function(e) {
if( ! e.success || e.error ) {
alert("Unable to get your location.");
}
f_lng = e.coords.longitude;
f_lat = e.coords.latitude;
});
return {
's_status': 'success',
'f_lat': f_lat,
'f_lng': f_lng
};
} catch( s_error ) {
return {
's_status': 'error',
's_message': s_error
};
}
}
Ti.App.GeoApp = {};
Ti.Geolocation.preferredProvider = Titanium.Geolocation.PROVIDER_GPS;
Ti.Geolocation.purpose = "testing";
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = 10;
if( Titanium.Geolocation.locationServicesEnabled === false ) {
Ti.API.debug('Your device has GPS turned off. Please turn it on.');
}
function updatePosition(e) {
if( ! e.success || e.error ) {
alert("Unable to get your location.");
Ti.API.debug(JSON.stringify(e));
Ti.API.debug(e);
return;
}
Ti.App.fireEvent("app:got.location", {
"coords" : e.coords
});
};
Ti.App.addEventListener("app:got.location", function(d) {
Ti.App.GeoApp.f_lng = d.longitude;
Ti.App.GeoApp.f_lat = d.latitude;
Ti.API.debug(JSON.stringify(d));
Ti.Geolocation.removeEventListener('location', updatePosition);
alert(JSON.stringify(d));
});
var tabGroup = Titanium.UI.createTabGroup();
//
// create base UI tab and root window
//
var window = Titanium.UI.createWindow({
backgroundColor:'#fff',
barColor:'#003333',
});
var tab1 = Titanium.UI.createTab({
icon:'KS_nav_views.png',
title:'Tab 1',
window:window
});
tabGroup.open();
Titanium.Geolocation.getCurrentPosition( updatePosition );
Titanium.Geolocation.addEventListener( 'location', updatePosition );
see more details here http://blog.clearlyinnovative.com/post/5384374513/titanium-appcelerator-quickie-get-location-android
Piggy-backing off of Aaron's answer, here is what worked for me on IPhone Simulator, IPhone, and Android phone (not Android simulator). Keep in mind that I use redux so the code will be a little different.
var path = Ti.Platform.name == 'android' ? Ti.Filesystem.resourcesDirectory : "../../";
var map = {
top: 0,
bottom: 0,
latitude: 0,
longitude: 0,
latitudeDelta: 0.1,
longitudeDelta: 0.1,
display: "map",
init: function (annotations, latitude, longitude, top, bottom, delta) {
if (top)
map.top = top;
if (bottom)
map.bottom = bottom;
if (delta) {
map.latitudeDelta = delta;
map.longitudeDelta = delta;
}
map.createMap(annotations, latitude, longitude);
map.createOptions();
map.getLocation();
},
createMap: function (annotations, latitude, longitude) {
map.mapView = Ti.Map.createView({
mapType: Ti.Map.STANDARD_TYPE, animate: true, regionFit: false, userLocation: true,
region: { latitude: latitude, longitude: longitude, latitudeDelta: map.latitudeDelta, longitudeDelta: map.longitudeDelta },
annotations: annotations, bottom: map.bottom, top: map.top, borderWidth: 1
});
if (!isAndroid) {
map.mapView.addAnnotation(annotations[0]);
}
map.mapView.selectAnnotation(annotations[0]);
win.add(map.mapView);
},
createOptions: function () {
//map/satellite displays.
var mapDisplay = new ImageView({ image: path + 'images/map/satellite-view.png', width: 70, height: 49, zIndex: 2, top: map.top + 5, right: 5 });
mapDisplay.addEventListener('click', function () {
if (map.display == "map") {
map.mapView.setMapType(Titanium.Map.SATELLITE_TYPE);
mapDisplay.image = path + "images/map/map-view.png";
map.display = "satellite";
}
else {
map.mapView.setMapType(Titanium.Map.STANDARD_TYPE);
mapDisplay.image = path + "images/map/satellite-view.png";
map.display = "map";
}
});
win.add(mapDisplay);
//crosshairs.
if(Ti.Geolocation.locationServicesEnabled) {
var centerDisplay = new ImageView({ image: path + 'images/map/crosshairs.png', width: 49, height: 49, zIndex: 2, top: map.top + 5, right: 80 });
centerDisplay.addEventListener('click', function () {
if(map.latitude != 0 && map.longitude != 0) {
info("setting user location to " + map.latitude + " / " + map.longitude);
//center map.
var userLocation = {
latitude: map.latitude,
longitude: map.longitude,
latitudeDelta: map.latitudeDelta,
longitudeDelta: map.longitudeDelta,
animate: true
};
map.mapView.setLocation(userLocation);
}
});
win.add(centerDisplay);
}
},
createAnnotation: function (title, subtitle, latitude, longitude, isLocation, addToMap) {
var mapAnnotation = Ti.Map.createAnnotation({
latitude: latitude, longitude: longitude,
title: title,
subtitle: subtitle,
animate: true
});
if (isAndroid) {
mapAnnotation.pinImage = path + (isLocation ? "images/map/blue-pin.png" : "images/map/purple-pin.png");
}
else {
mapAnnotation.pincolor = isLocation ? Ti.Map.ANNOTATION_PURPLE : Ti.Map.ANNOTATION_RED;
}
if (addToMap)
map.mapView.addAnnotation(mapAnnotation);
return mapAnnotation;
},
updateAnnotation: function (mapAnnotation, title, subtitle, latitude, longitude, isLocation) {
if (mapAnnotation) {
map.mapView.removeAnnotation(mapAnnotation);
mapAnnotation = map.createAnnotation(title, subtitle, latitude, longitude, isLocation);
map.mapView.addAnnotation(mapAnnotation);
map.mapView.selectAnnotation(mapAnnotation);
}
},
addAnnotation: function (mapAnnotation) {
map.mapView.addAnnotation(mapAnnotation);
},
removeAnnotation: function (mapAnnotation) {
map.mapView.removeAnnotation(mapAnnotation);
},
selectAnnotation: function (mapAnnotation) {
map.mapView.selectAnnotation(mapAnnotation);
},
createRoute: function (name, points) {
var route = {
name: name, points: points, color: "#7c74d4", width: 4
};
map.mapView.addRoute(route);
setTimeout(function () { map.mapView.regionFit = true; }, 700);
},
getLocation: function() {
Ti.Geolocation.preferredProvider = Ti.Geolocation.PROVIDER_GPS;
Ti.Geolocation.purpose = "testing";
Ti.Geolocation.accuracy = Ti.Geolocation.ACCURACY_BEST;
Ti.Geolocation.distanceFilter = 10;
if(!Ti.Geolocation.locationServicesEnabled) {
//alert('Your device has GPS turned off. Please turn it on.');
return;
}
function updatePosition(e) {
if(!e.success || e.error) {
info("Unable to get your location - " + e.error);
return;
}
info(JSON.stringify(e.coords));
map.latitude = e.coords.latitude;
map.longitude = e.coords.longitude;
Ti.Geolocation.removeEventListener('location', updatePosition);
};
Ti.Geolocation.getCurrentPosition(updatePosition);
Ti.Geolocation.addEventListener('location', updatePosition);
}
};
Have you tried setting a timeout to make sure the e.coords is set before you use it, it has been suggested as a temporary fix?
setTimeout(function() {
return e.coords
}, 1000);