Get users location in ons.ready not working - html

I have the following code:
ons.ready( function() {
navigator.geolocation.getCurrentPosition(
function( position ) {
geo.lat = position.coords.latitude;
geo.lon = position.coords.longitude;
}
);
} );
Sometimes, but not all the time I get the following error:
Location access is not available.
Error in Error callbackId: Geolocation54410059
I need the user's location to load data into the main page of my app. Where is the best place to do this?

ons.ready fire when the dom is loaded, you are using a cordova plugin in order to get geolocation position. So you can't use it before cordova is ready.
Just do:
document.addEventListener('deviceready', function () {
// now cordova is ready
navigator.geolocation.getCurrentPosition(function( position ) {
geo.lat = position.coords.latitude;
geo.lon = position.coords.longitude;
});
}, false);
And it will be fine I think.
Edit :
Try adding those options to your function :
navigator.geolocation.getCurrentPosition(function( position ) {
geo.lat = position.coords.latitude;
geo.lon = position.coords.longitude;
}, { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true });
you can put whatever value you want for 'enableHighAccuracy' and 'maximumAge' but you must provide a 'timeout' option because there is some quirks in android:
Android Quirks
If Geolocation service is turned off the onError callback is invoked
after timeout interval (if specified). If timeout parameter is not
specified then no callback is called.

Related

ol3 geocoder zoom level issue in chrome

I am trying to add ol3 geocoder control in my project. I have set fix zoom level and it is working in Mozilla and it comes properly with appropriate zoom level but in google chrome it is not working. It takes the location on deep zoom in level. I have to zoom out to check surrounding places.
var geocoder = new Geocoder('nominatim', {
provider: 'google',
key:' AIzaSyClQ0GOW55zhw4PvFh73FyGLHdSd4bJfpM',
lang: 'en',
placeholder: 'Search Location...',
limit: 5,
keepOpen: true,
autoComplete: true,
});
map.addControl(geocoder);
//Listen when an address is chosen
geocoder.on('addresschosen', function(evt){
var
feature = evt.feature,
coord = evt.coordinate,
address_html = feature.get('address_html');
content.innerHTML = '<p>'+address_html+'</p>';
if (coord) {
//alert("if--");
map.getView().setZoom(7);
overlay.setPosition(coord);
} else {
map.getView().setZoom(8);
overlay.setPosition(coord);
}
});
When using the latest version of geocoder (3.0.1) it seems you can set the zoom level within the function. I had the same problem when I switched to new version, but I played around and found that it works perfectly like this:
geocoder.on('addresschosen', function (evt) {
window.setTimeout(function () {
view.setZoom(12);
popup.show(evt.coordinate, evt.address.formatted);
}, 1000);
});
Obviously, use whatever zoom value you like.

PhantomJS failing to load Google Maps

My end goal is to open a local html file with javascript embedded, creating a map with polygons, and take a screenshot of it using PhantomJS. I have written a simple JS file to do this:
var page = require('webpage').create();
page.open('https://www.google.com/maps', function(status) {
console.log('State: ' + status);
if(status === 'success') {
page.render('example.pdf', {format: 'pdf', quality: '100'});
}
phantom.exit();
});
This returns the error:
ReferenceError: Can't find variable: google
I've tried this on a local html file and on other websites using google maps and I keep getting the same error. I have been successful in taking a screenshot of other websites without google maps. Searching the internet it doesn't seem like people have had issues like this, and have been successful in taking screenshots of pages with google maps...so I'm wondering what could be wrong.
Another note: I installed PhantomJS as a gem in my rails project and am running the javascript file through the rails console using this gem. I have tried it using the standard installation of PhantomJS (v 2.0.0) and it still didn't work.
You'll have to wait for an element in the DOM.
for example on maps.google.com, you can wait for the watermark which is loaded after all tiles are loaded.
var page = require('webpage').create();
page.open('https://www.google.com/maps', function (status) {
console.log('State: ' + status);
if (status === 'success') {
waitFor(function () {
return page.evaluate(function () {
var document_contains_watermark =
document.body.contains(document.getElementById('watermark'));
return document_contains_watermark;
});
}, function () {
page.render('maps-google-com.pdf', {format: 'pdf', quality: '100'});
phantom.exit();
});
}
});
function waitFor(testFn, onReady) {
var loaded = false;
var interval = setInterval(function () {
loaded = testFn();
if (loaded) {
onReady();
clearInterval(interval);
}
}, 1000);
}
If you want to take a screenshot on a page that you developed, use the same above logic but append by yourself an element on the google maps idle event.
google.maps.event.addListenerOnce(map, 'idle', function () {
var loadedElem = document.createElement('div');
loadedElem.setAttribute("id", "idLoadedElem");
document.body.appendChild(loadedElem);
});
you should give puppeter a go, it makes that easy:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.pdf'});
await browser.close();
})();

chrome.omnibox ceases working after period of time. Begins working after restarting extension

I'm leveraging Google Chrome's omnibox API in my extension.
Current users, including myself, have noticed that the omnibox ceases responding entirely after an undetermined state change or a period of time lapsing. Typing the word to trigger entering into "omnibox" stops having any effect and the URL bar does not shift into omnibox mode.
Restarting Google Chrome does not fix the issue, but restarting my plugin by unchecking and then re-checking the 'enabled' checkbox on chrome://extensions does resolve the issue.
Does anyone have any suggestions on what to investigate? Below is the code used. It is only loaded once through my permanently persisted background page:
// Displays streamus search suggestions and allows instant playing in the stream
define([
'background/collection/streamItems',
'background/model/video',
'common/model/youTubeV2API',
'common/model/utility'
], function (StreamItems, Video, YouTubeV2API, Utility) {
'use strict';
console.log("Omnibox LOADED", chrome.omnibox);
var Omnibox = Backbone.Model.extend({
defaults: function () {
return {
suggestedVideos: [],
searchJqXhr: null
};
},
initialize: function () {
console.log("Omnibox INITIALIZED");
var self = this;
chrome.omnibox.setDefaultSuggestion({
// TODO: i18n
description: 'Press enter to play.'
});
// User has started a keyword input session by typing the extension's keyword. This is guaranteed to be sent exactly once per input session, and before any onInputChanged events.
chrome.omnibox.onInputChanged.addListener(function (text, suggest) {
// Clear suggested videos
self.get('suggestedVideos').length = 0;
var trimmedSearchText = $.trim(text);
// Clear suggestions if there is no text.
if (trimmedSearchText === '') {
suggest();
} else {
// Do not display results if searchText was modified while searching, abort old request.
var previousSearchJqXhr = self.get('searchJqXhr');
if (previousSearchJqXhr) {
previousSearchJqXhr.abort();
self.set('searchJqXhr', null);
}
var searchJqXhr = YouTubeV2API.search({
text: trimmedSearchText,
// Omnibox can only show 6 results
maxResults: 6,
success: function(videoInformationList) {
self.set('searchJqXhr', null);
var suggestions = self.buildSuggestions(videoInformationList, trimmedSearchText);
suggest(suggestions);
}
});
self.set('searchJqXhr', searchJqXhr);
}
});
chrome.omnibox.onInputEntered.addListener(function (text) {
// Find the cached video data by url
var pickedVideo = _.find(self.get('suggestedVideos'), function(suggestedVideo) {
return suggestedVideo.get('url') === text;
});
// If the user doesn't make a selection (commonly when typing and then just hitting enter on their query)
// take the best suggestion related to their text.
if (pickedVideo === undefined) {
pickedVideo = self.get('suggestedVideos')[0];
}
StreamItems.addByVideo(pickedVideo, true);
});
},
buildSuggestions: function(videoInformationList, text) {
var self = this;
var suggestions = _.map(videoInformationList, function (videoInformation) {
var video = new Video({
videoInformation: videoInformation
});
self.get('suggestedVideos').push(video);
var safeTitle = _.escape(video.get('title'));
var textStyleRegExp = new RegExp(Utility.escapeRegExp(text), "i");
var styledTitle = safeTitle.replace(textStyleRegExp, '<match>$&</match>');
var description = '<dim>' + video.get('prettyDuration') + "</dim> " + styledTitle;
return {
content: video.get('url'),
description: description
};
});
return suggestions;
}
});
return new Omnibox();
});
As far as I'm aware the code itself is fine and wouldn't have any effect on whether I see omnibox or not.
You can find full source code here: https://github.com/MeoMix/StreamusChromeExtension/blob/master/src/js/background/model/omnibox.js

Phonegap not detecting accurate location

I am using HTML5 Geolocation API in phonegap to precisely detect my location. I am working from India I should ideally be able to see my location i.e. Pune, India but it doesn't do so.
It detects 'San Francisco, CA, USA' as my location. What might be the problem?
Thank you all. Help is highly appreciated.
Let me share the code :)
document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is loaded and it is now safe to make calls Cordova methods
//
function onDeviceReady() {
// onSuccess Callback
// This method accepts a `Position` object, which contains
// the current GPS coordinates
//
var onSuccess = function(position) {
var lattitude = position.coords.latitude;
var longitude = position.coords.longitude;
//Ajax Call
$.ajax({
url: 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+lattitude+','+longitude+'&sensor=true',
success: function(data){
alert(data.results[0].formatted_address);
//alert(data.results[1].formatted_address);
},
error: function(data){
alert('error');
}
});//Ajax call ends
};
function onError(error) {
alert('code: '+ error.code + '\n' + 'message: ' + error.message + '\n');
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
If you're using the iOS simulator you will always get SF as the location as it has a static location setting. You can however use this nifty tool to emulate in browser and it will allow you to mess with location settings and more.
http://emulate.phonegap.com/

navigator.geolocation getCurrentPosition not updating in Chrome Mobile

I have created a site (can be accessed at http://dev.gkr33.com) which is designed for a smartphone and attempts to use the navigator.geolocation api and grab your position via getCurrentPosition. This seems to work initially, however if you try to refresh the page it always brings back the last GPS position. I have added some debug information on the page which grabs the time of the getCurrentPosition return and after the initial positioning it always returns the same time (down to the millisecond).
This only seems to happen in Chrome Mobile. If I browse into the site via the stock Android browser it works fine every time.
The code is shown below;
<script type="text/javascript">
(function ($) {
$(document).ready(function() {
var options = { enableHighAccuracy: true, maximumAge: 0, timeout: 60000 };
var position;
// empty the current html elements, not strictly necessary but
// I'm clutching at straws
$('#debug-latlng').empty();
$('#debug-time').empty();
$('#debug-address').empty();
// Let's try and find out where we are
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(gotPos, gotErr, options );
} else {
gotErr();
}
// We've got our position, let's show map and update user
function gotPos(position) {
var info;
info = position.coords.latitude+','+position.coords.longitude;
$('#debug-latlng').text(info);
$('#debug-time').text(parseTimestamp(position.timestamp));
// the following json call will translate the longitude and
// latitude into an address (a wrapper for google's geocode call)
$.getJSON('http://dev.gkr33.com/api.php', { req: "getLocationInfo", latlng: $('#debug-latlng').text() }, function(json) {
$('#debug-address').text( json['results'][0]['formatted_address'] );
});
var myLatLng = new google.maps.LatLng( position.coords.latitude, position.coords.longitude );
var mapOptions = {
zoom: 12,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var marker = new google.maps.Marker({
position: myLatLng,
title: 'You are here',
animation: google.maps.Animation.DROP
});
marker.setMap(map);
} //gotPos
// Trap a GPS error, log it to console and display on site
function gotErr(error) {
var errors = {
1: 'Permission denied',
2: 'Position unavailable',
3: 'Request timeout'
};
console.log("Error: " + errors[error.code]);
$('#debug-latlng').text('GPS position not available');
} //gotErr
// Make timestamp human readable
function parseTimestamp(timestamp) {
var d = new Date(timestamp);
var day = d.getDate();
var month = d.getMonth() + 1;
var year = d.getFullYear();
var hour = d.getHours();
var mins = d.getMinutes();
var secs = d.getSeconds();
var msec = d.getMilliseconds();
return day + "." + month + "." + year + " " + hour + ":" + mins + ":" + secs + "," + msec;
} // parseTimestamp
});
}) (jQuery);
</script>
I have played around with various values for the maximumAge and timeout, but nothing seems to affect the same position.coords and position.time values.
I think there maybe an issue with Chrome Mobile, but I don't wanna assume too much at this point in time and just need clarification that I haven't made a mistake of muppet-like proportions in my code.
Many thanks for any help you can provide.
UPDATE: I suppose I should have said that I have tested this on two Android devices; HTC One X+ and a Samsung Galaxy Tab 7.7 with the same result. On both the stock browser works fine, and on both Chrome doesn't refresh the position. Will test on an Apple Device later :)
I never got to the bottom of this issue, but I got a way around the problem by utilising the watchPosition call, and wrapping this in a 5 second wait before clearing the watchID. Check the code below:
var options = { enableHighAccuracy: true, maximumAge: 100, timeout: 50000 };
if( navigator.geolocation) {
var watchID = navigator.geolocation.watchPosition( gotPos, gotErr, options );
var timeout = setTimeout( function() { navigator.geolocation.clearWatch( watchID ); }, 5000 );
} else {
gotErr();
}
I haven't played around with the "options" values or the timeout delay at the moment, but the above code brings back accurate positioning info on every platform I've tried.
Hope this helps someone with the same issue :)
I finally found a working version for firefox, chrome & default navigator in android (4.2 tested only):
function getGeoLocation() {
var options = null;
if (navigator.geolocation) {
if (browserChrome) //set this var looking for Chrome un user-agent header
options={enableHighAccuracy: false, maximumAge: 15000, timeout: 30000};
else
options={maximumAge:Infinity, timeout:0};
navigator.geolocation.getCurrentPosition(getGeoLocationCallback,
getGeoLocationErrorCallback,
options);
}
}
getCurrentLocation() no longer works on insecure origins in Chrome browsers. Switch to a secure original (HTTPS) to enable.