Geolocation fail in case of inactive mobile browser - javascript

I am using following code:
var fail = function(error) {
alert("Unable to get location");
};
function getGeo() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
success,
fail,
{maximumAge: 50000, timeout: 30000, enableHighAccuracy: true});
}
};
Mostly It works but often it gives geolocation error and unable to get coordinates.
How can I make possible to get coordinates no matter browser window is inactive or browser is in background or mobile itself in sleep mode?

Without specifics of "geolocation error" my answer can no be complete but: -
At present you cannot get coordinates if browser window is inactive or browser is in background or mobile itself in sleep mode, unless you are developing a hybrid App with something like phonegap/cordova. (Firefox has the exception of continuing to service watchPosition() if the App is foregrounded but the phone is asleep.)
I have made several suggestions to W3C, IETF, Chrome Dev, Mozilla Dev, and Edge Dev regarding a workable solution using the Service Worker Extensibility functionality for a Javascript-only solution.
Briefly, the UA tracks Geolocation changes and if within range of a dev supplied filter, a ServiceWorker will be instantiated which may foreground the App or merely notify the App Server.
Please pursue this issue with the relevant bodies as the idea is beginning to gain traction.
HTH

Related

navigator.mediaDevices.getUserMedia API rejecting with error "NotReadableError: Concurrent mic process limit."

During an active media flow(voice) navigator.mediaDevices.getUserMedia works fine when connected to internal mic, as soon as I switch to Bluetooth device and rerun the same API to fetch the latest media stream, I get the error "NotReadableError: Concurrent mic process limit."
I browsed throw many forums, as suggested by many that this error generally occurs in Firefox, Mac OS when multi tabs are trying to access mic or/and camera.
I made sure that only single tab is opened in Firefox browser, still see the same error.
Any leads on this shall be appreciated.
Below is the code snippet
constraints = {
"audio": {"deviceId": deviceId },
"video": false
}
let temp;
navigator.mediaDevices.getUserMedia(constraints).then(function(stream){
temp = stream;
}).catch(function(err) {
console.log(err.name + ": " + err.message);
});
Return below error message
NotReadableError: Concurrent mic process limit.
NOTES: Works fine in Chrome and Edge
Browser : Firefox 70.0.1 (64-bit)
OS : MacOS Mojave
NotReadableError: Concurrent mic process limit.
This means you cannot open more than one microphone at a time, per process, in Firefox right now. This limitation is a known bug that Mozilla is working on fixing.
In practice, this means you cannot open more than one microphone from your site (same-origin tabs typically share the same process). Make sure to call track.stop() when you're done with a mic.
Comes up during device switching
Few sites actually need to use two mics at once. But sites still run into this bug when switching from one microphone to another, because they generally open the new microphone before closing the old one.
Workaround
Call track.stop() on your existing microphone track, before attempting to obtain a track from a different microphone.
This strategy is similar to mobile where only one camera can be opened at once. The best approach is a fallback strategy: only stop the old track if necessary (that way there's no impact on other browsers):
async function getUserMedia(constraints, oldTrack) {
try {
return await navigator.mediaDevices.getUserMedia(constraints);
} catch (e) {
if (e.name != "NotReadableError") throw e;
oldTrack.stop();
return await navigator.mediaDevices.getUserMedia(constraints);
}
}
Done all that, but still get the same mic as before
When switching devices, use deviceId: {exact: deviceId}. I.e.
const constraints = {
audio: {deviceId: {exact: deviceId}},
};
This tells the browser you want this specific device or failure, and avoids a recent regression in Firefox.
While fallbacks to other devices are normally good, they're not when the user is trying to pick a specific device.

How to enable geolocation using Firefox/Chromium on Ubuntu 16.04

I'm building a node app that returns the user's geolocation, but I'm having a hard time testing it because I can't access geolocation on my computer. I tried using my localhost server in both Firefox and Chromium - Firefox asks for my permission but then can't retrieve it, and Chromium doesn't even get that far. When I deploy it to Heroku, I still can't access it on the computer. On my iPhone, Firefox still has no luck but Safari can do it. I don't know if my problem is in Ubuntu itself (can it block things like that?) or if both Firefox and Chromium have the same issue.
I doubt my code will be especially useful, but here it is anyway:
const locationButton = jQuery('#send-location');
locationButton.on('click', function() {
if (!navigator.geolocation) return alert('Geolocation not supported by your browser.');
navigator.geolocation.getCurrentPosition(function (position) {
socket.emit('newLocationMessage', {
latitude: position.coords.latitude,
longitude: position.coords.longitude
}, function (mapLink) {
alert(mapLink);
});
}, function () {
alert('unable to fetch location.')
});
});
The app is also up at http://rocky-brook-97128.herokuapp.com/.
Thanks for any guidance on this!
As of Chrome 50, the Geolocation API will only work on secure contexts such as HTTPS. If your site is hosted on an non-secure origin (such as HTTP) the requests to get the users location will no longer function.
Try it on https.
https://rocky-brook-97128.herokuapp.com/
(1) In a new tab, type or paste about:config in the address bar and press Enter/Return.
(2) In the search box above the list, type or paste geo and pause while the list is filtered
(3) If the geo.wifi.uri preference is bolded and "modified" or "user set", you can right-click > Reset it to the default
If Firefox sends anything to the geolocation service, the address should appear in the Browser Console
You can inspect and manage the permissions for all domains on the about:permissions page

Geolocation API doesn't work on mobile

I'm writing my web application on React/Redux. And I need to get user location with a help of Geolocation API. On desktop browsers everything works fine, but on mobile phones (checked out on Xiaomi Redmi Note 3 and iPhone 5s) it throws error code 1 - permission denied. And it doesn't requests any permissions to get the location.
Here's a test sample which I ran on my site:
componentDidMount() {
if (window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(position => {
alert(position.coords.latitude + ' ' + position.coords.longitude);
}, err => {
alert('ERROR: ' + err.code);
});
} else {
alert('Geolocation API is not supported!');
}
}
What's the solution of this problem?
Got the same Problem... Solved:
Check your phone permissions for sharing your location.
On iPhone:
Settings -> Location Services -> [your Browser]
https://support.apple.com/en-ca/HT203033
Added:
Chrome requires https for geolocation usage:
https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only
I've got the solution. I'm using the Web Application Manifest and it needed to set the permission to use Geolocation API.
We just need to set an "required_features" option at manifest.webapp file:
{
"required_features": ["geolocation"]
}
Hope it will be useful for somebody ;)
As of the Year 2021, this still does not work.
This is the link in that error message.In case you're wondering, it talks about "prefer secure origins for powerful new features" and location is consider one of those powerful features.
To generate the above, update the error section as follows:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
// other
},
err => {
// include the "code" part
alert(`ERROR(${err.code}): ${err.message}`)
});
};
On desktop during development...It works because if you read from the above link you will note that localhost is considered a secure origin.
In fact, even the chrome link shared in #chrisheyn's answer above, there is a section "Does this affect local development?" and explains why this should work on locahost.
So how about Mobile during development?Notice that react serves the app over your network e.g. http://192.168.0.134:3000 and that is definitely not considered a "secure origin" at all.
This question "Can I detect at runtime if the geolocation was blocked because of not being on a secure context
" mentions that... Errors due to this secure-context issue will return a code of 1 which is a "Permission Denied Error".
What's the solution?
Until the react team updates how your mobile picks the app during development, there is absolutely nothing you can to solve this issue.
To use the HTML5 Geolocation API, you will need to run the app over HTTPS. This means push your app to the cloud/host (in order to test this feature) or if you can some manage to get this network url http://192.168.0.134:3000 to do https The latter option, i believe, is much harder but I'd be interested to know if someone pulls it off.

Chrome extensions for silent print?

I have made a silent print web application that prints a PDF file. The key was to add JavaScript to the PDF file that silently print itself.
To do this I open the PDF with acrobat reader in chrome, that allow me to execute the script (with the proper permissions).
But as it was announced this solution won't work after chrome 45 because the npapi issue.
I guess a possible solution could be to use the recently release printProvider of chrome extensions.
Nevertheless I can't imagine how to fire any of the printProvider events.
So the question is: Is ok to think in chrome extensions to make a silent print web application, and how can I fire and handle a print job for an embedded PDF of a HTML Page.
Finally I reached an acceptable solution for this problem, as I couldn't find it out there, but read to many post with the same issue I will leave my solution here.
So first you need to add your printer to the Google Cloud Print and then you will need to add a proyect to the Google Developers Console
Then add this script and any time you need to print something execute the print() function. This method will print the document indicated in the content
The application will ask for your permission once to manage your printers.
function auth() {
gapi.auth.authorize({
'client_id': 'YOUR_GOOGLE_API_CLIENT_ID',
'scope': 'https://www.googleapis.com/auth/cloudprint',
'immediate': true
});
}
function print() {
var xhr = new XMLHttpRequest();
var q = new FormData()
q.append('xsrf', gapi.auth.getToken().access_token);
q.append('printerid', 'YOUR_GOOGLE_CLOUD_PRINTER_ID');
q.append('jobid', '');
q.append('title', 'silentPrintTest');
q.append('contentType', 'url');
q.append('content',"http://www.pdf995.com/samples/pdf.pdf");
q.append('ticket', '{ "version": "1.0", "print": {}}');
xhr.open('POST', 'https://www.google.com/cloudprint/submit');
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.auth.getToken().access_token);
xhr.onload = function () {
try {
var r = JSON.parse(xhr.responseText);
console.log(r.message)
} catch (e) {
console.log(xhr.responseText)
}
}
xhr.send(q)
}
window.addEventListener('load', auth);
<script src="https://apis.google.com/js/client.js"></script>
Anyway this script throw a 'Access-Control-Allow-Origin' error, even though this appears in the documentation... I couldn't make it work :(
Google APIs support requests and responses using Cross-origin Resource Sharing (CORS). You do not need to load the complete JavaScript client library to use CORS. If you want your application to access a user's personal information, however, it must still work with Google's OAuth 2.0 mechanism. To make this possible, Google provides the standalone auth client — a subset of the JavaScript client.
So to go throw this I had to install this chrome extension CORS. I'm sure that some one will improve this script to avoid this chrome extension.
You can register an Application to a URI Scheme to trigger the local application to print silently. The setting is pretty easy and straightforward. It's a seamless experience. I have posted the solution here with full example:
https://stackoverflow.com/a/37601807/409319
After the removal of npapi, I don't believe this is possible solely programmatically. The only current way I know to get chrome to print silently is using chrome kiosk mode, which is a flag (mode) you have to set when starting chrome.
Take a look at these SO posts:
Silent printing (direct) using KIOSK mode in Google Chrome
Running Chrome with extension in kiosk mode
This used to be possible using browser plugins (e.g. Java + NPAPI, ActiveX) but has been blacklisted by most browsers for several years.
If interested in modern solutions that use similar techniques, the architecture usually requires the following:
WebSocket, HTTP or Custom URI connection back to localhost
API that talks through web transport (JavaScript or custom URI scheme) to an app running locally.
A detail of projects (several of them are open source) that leverage these technologies are available here:
https://stackoverflow.com/a/28783269/3196753
Since the source code of these projects can vary (hundreds of lines to tens-of-thousands of lines), a code snippet would be too large unless a inquiring about a specific project's API.
Side note: Some technologies offer dedicated cloud resources, which add convenience at the expense of potential latency and privacy. At the time of writing this, the most popular "free" cloud solution -- Google Cloud Print -- is slated to be retired in December 2020.

WebSocket supported in Android Stock Browser or not?

using https://github.com/einaros/ws
Server:
var WebSocketServer=require('ws').Server,wss=new WebSocketServer({port:8004});
wss.on('connection',function(s) {
s.on('message',function(_){console.log('received: '+_);});
});
Client:
var s=new WebSocket('ws://mysite.com:8004');
//android default browser dies here <---------------?
s.onopen=function(){
$('body').css({'background':'green'});
s.send('hi');
};
I have to ask why android default browser does not open the connection?
I visit www.websocket.org/echo.html on the default android browser and it says This browser supports websocket. so what is the problem?
This simple code works on iphone safari, windows chrome, android mobile chrome no problem.
On android default browser I can also console.dir(window.WebSocket); and it shows the WebSocket Object no differently than other browsers.
If someone knows why, please tell.
Thanks
UPDATE
if (!window.WebSocket && window.MozWebSocket) {
window.WebSocket = window.MozWebSocket;
alert('MozWebSocket');
}
else if (!window.WebSocket) {
alert("WebSocket not supported by this browser");
}
else{
alert('wtf!? '+window.WebSocket);
}
This gives me a console log of:
wtf!? function WebSocket(){[native code]}
The Android stock browser does not, in fact, support WebSocket.
Some work was apparently done in preparation for adding support, so the API in the browser is there, i.e. you can create a WebSocket object. It's just that this doesn't actually do anything behind the scenes.
This results in a simple feature support check, which just attempts to create the socket object, showing WebSocket support. Check the readyState for a created WebSocket object instead, and you'll see that this never changes from "0".
Starting with Android 4.4, there is no stock browser anymore. The Web view component has been switched to Chrome for Android - and this does support WebSocket.

Categories

Resources