Is HTML5 browser geolocation feature on mobile available while screen off/ suspend? - android

To substitute my usage of native apps that allow to keep track of my position, I wanted to generate a PWA using the HTML5 Goelocation API.
The result I have been able to achieve so far seems to point a inferior functionality of the HTML5 Goelocation API compared to native Android API.
Below is the code I have used and the issue is, that the PWA/ website application only receives infrequent updates. Additionally the app only receives position while the screen is not off.
This puts a huge obstacle into having a PWA being to track for instance my bike tour, since I cannot keep the screen and browser in the foreground, while ideed I wished the PWA would simply continues running even when the screen is off.
Now I am aware that in most cases a device user and privacy aware person would benefit from the useragent/browser to cut the waste of resources and limit privacy loss by disabling the very feature I search.
In essence however I have looked over the MDN documentation and besides the PositionOptions I was yet unable to find any clue about the guarantees of the API.
Find below the way I have sought to make it work as a code.
Does + Should HTML5 Goelocation API work when screen of on a mobile?
Is there a concrete information about if and how much geolocation information is returedn? like frequency/delay of update and like geofencing imprecision ?
Could for instance google maps navigation work in the browser itself?
My platform is Gecko on Android. If better results could be achieved in Chromium on Android I would be happy to hear about that too.
On Android I use firefox. In it I wanted to have my website provide a page that keeps track of my movements via the geolocation API, in order to replace my strave.
window.addEventListener("load",function(){
var a= document.createElement("div");
var textarea = document.createElement("textarea");
//textarea.value="aaaa"
textarea.style.display="block"
textarea.style.minHeight="5cm"
textarea.style.width="100%"
document.body.appendChild(a);
document.body.appendChild(textarea);
if(confirm("reset data?")){
localStorage.clear() ;
}
localStorage.setItem("start"+Date.now(),startInfo);
var startInfo = Object.keys(localStorage).length+ " " +Date.now()+ " " + (Date.now() % 864000);
var lastTime=0,lastLat=0,lastLon=0,count=0,lastDistance=0;
var startTime = Date.now();
var distance = 0;
if('geolocation' in navigator) {
a.innerHTML="<h2>super wir haben geolocation!</h2>";
setInterval(()=>{
navigator.geolocation.getCurrentPosition((position) => {
// var a = document.createElement("div");
count++;
a.innerHTML="<h1>"+(((Date.now()-startTime)/1000)|0)+" "+((distance*100|0)/100)+"</h1><h3>"+startInfo+"</h3><h2>date="+(new Date()).toString()+"<br>lang="+position.coords.latitude+" long="+ position.coords.longitude+"</h2>";
var lat = ((position.coords.latitude * 10000000) | 0)
var lon = ((position.coords.longitude * 10000000) | 0)
var time = Date.now();
var deltaTime = time - lastTime;
var deltaLat = lat - lastLat;
var deltaLon = lon - lastLon;
if(Math.abs(deltaLat)>100000 || Math.abs(deltaLon) > 100000)
{
} else{
distance += Math.sqrt(deltaLat*deltaLat+deltaLon*deltaLon);
}
var deltaDistance = distance - lastDistance;
lastLat=lat;
lastLon=lon;
lastTime=time;
lastDistance=distance;
newline = (((Date.now()-startTime)/1000)|0) + " dist=" + distance + "("+deltaDistance+") lat=" + lat + "("+deltaLat+") lon=" + lon + "("+deltaLon+") ";
textarea.value = newline + "\n" + textarea.value;
localStorage.setItem("P"+(Date.now()%864000),deltaLat+" "+deltaLon+" "+deltaTime);
},function(){},{timeout:900});
},1000);
} else {
a.innerHTML="<h2> shit</h2>";
}
});

Related

iOS Swift alternative(s) to Android String Tokenizer function

I am facing Performance issues with iOS Swift function to the word-wrap streaming text received in real-time**
We have written an iOS function to perform word-wrapping based on character count on streaming text received in real-time, to display on an OLED. We are trying to replicate what the Android StringTokenizer class and methods do, since iOS Swift does not have an equivalent class/method. But we have performance issues with this function (delay in the output of wrapped words compared to the streaming text being received). We are looking for the best possible method/solution/class in Swift which can handle the entire process of word wrapping of streaming text with minimum delay.
Background:
We are developing an iOS mobile app to convert speech to text in real-time using cloud-based automatic speech-to-text (STT) model APIs including STT APIs from Google, Azure & IBM, and display the transcribed text on an OLED display via a BLE device.
The app uses the mobile device’s microphone to capture “endless” or “infinite” streaming audio feeds, streams the audio to the cloud STT API, and receives stream speech recognition (transcription) results in real-time as the audio is processed.
Unlike standard speech-to-text implementations in voice assistants which listen to voice commands, wait for silence and then give the best output, in infinite streaming, there is a continuous stream of input audio being sent to the STT API which returns interim and final transcription results continuously.
As the transcription data is received from the API (interim/final), the app performs word-wrapping logic to prepare the text for display on the OLED. This logic depends on the number of characters that can be displayed on one line of the OLED and the number of lines in the display.
For example, on our current OLED, we can display 18 characters in one line and a maximum of 5 lines at a time. So if a string of than 18 characters is received from the STT API, the app logic has to find the appropriate space character in the string after which to break it and display the remaining string on the next line(s). . Here’s an example of a string received from the STT API:
TranscribeGlass shows closed captions from any source in your field of view
The expected result on the 5 lines of the OLED after performing word wrapping:
TranscribeGlass
shows closed
captions from any
source in your
field of view
Explanation:
Line 1 - “TranscribeGlass” - because “TranscribeGlass shows” exceeds 18 characters so break the string after the space before “shows”, and wrap it to the next line
Line 2 - “shows closed” - because“shows closed captions” exceeds 18 characters, break the string after the space before “captions”
Line 3 - “captions from any” - because “captions from any source” exceeds 18 characters, break the string after the space before “source”
Line 4 - “source on in your” - because “source on in your field” exceeds 18 characters, break the string after the space before “field”
Line 5 - “field of view” - no wrapping needed since the string is <= 18 characters
In Android, we have a ready-made StringTokenizer class & methods available that allows an application to break a string into tokens.
Our iOS Swift function:
We have written a function WriteOnlyCaption(), which takes a string as input and performs the word wrapping. See the code below:
For strings which has less than 18 characters, we are using the below function
public func writeOnlyCaption(text:String, isFinalBLE: Bool) {
print("TEXT IS NOW:\(text)")
var sendString:String = " "
var previousWrapLocation = 0
var currentWrapLocationIndex = characterPerLine
while(text.count - previousWrapLocation > characterPerLine) {
while(text[currentWrapLocationIndex] != " ") {
//print("While CurrentWrapLocationIndex Index \(currentWrapLocationIndex)")
currentWrapLocationIndex -= 1
}
sendString = sendString + String(text[previousWrapLocation...currentWrapLocationIndex]) + "\n"
line.addLineIndex(textIndex: currentWrapLocationIndex)
currentWrapLocationIndex += 1
previousWrapLocation = currentWrapLocationIndex
currentWrapLocationIndex = currentWrapLocationIndex + characterPerLine
}
sendString = sendString + String(text[previousWrapLocation..<text.count]) + "\n"
print("sendSting:->\(sendString)")
line.addLineIndex(textIndex: sendString.count)
line.setSendString(sendText: sendString)
line.tooString()
if previousLine == 0 {
previousLine = line.getLines().count
}
print("previousLine:->\(previousLine)")
var seed = ""
var counter = 0
var stringData = line.getSendString().components(separatedBy: "\n")
stringData.removeLast()
if stringData.count < 5 {
repeat {
if counter >= 0 {
seed = seed + stringData[counter] + "\n"
}
counter += 1
} while(stringData.count != counter)
} else {
counter = stringData.count - 5
repeat {
if counter > 0 {
seed = seed + stringData[counter] + "\n"
}
counter += 1
} while(stringData.count != counter)
}
print("Seeeddddddd:->\(seed)")
print("counter: \(counter)")
if seed != "" {
if isFinalBLE {
var seedBytes = seed.bytes
if previousLine == line.getLines().count {
seedBytes.append(0x03)
} else if line.getLines().count > previousLine {
seedBytes.append(0x02)
seedBytes.append(0x03)
}
seedBytes.append(0x00)
print("-- seedBytes: \(seedBytes) --")
previousLine = line.getLines().count
self.writeDataWithResponse(writeData: Data(seedBytes), characteristic: self.getCharsticFrom(UUID: CHAR.GLASS_WRITE)!)
} else {
var seedBytes = seed.bytes
if previousLine == line.getLines().count {
//seedBytes.append(0x00)
} else if line.getLines().count > previousLine {
if line.getLines().count - previousLine == 1 {
seedBytes.append(0x02)
} else if line.getLines().count - previousLine == 2{
seedBytes.append(0x02)
seedBytes.append(0x02)
} else {
seedBytes.append(0x02)
}
}
seedBytes.append(0x00)
print("-- seedBytes: \(seedBytes) --")
previousLine = line.getLines().count
self.writeDataWithResponse(writeData: Data(seedBytes), characteristic: self.getCharsticFrom(UUID: CHAR.GLASS_WRITE)!)
}
}
}
As you can see, we are using four while loops to perform the word wrapping correctly and send it to the OLED.
The main issue with this function is that four while loops and different if-else conditions create lots of delays (varies from 450ms to 900ms) while processing the text string, and this results in poor performance - either a lag in the display of text on the OLED compared to the streaming audio or entire chunks of transcribed text get skipped.

get offline GPS coordinates on android device

Firstly, I'm not a developer or programmer so any help here would be really appreciated! I have a form for use on android mobile devices which launches in Google Chrome. The users can use this form when offline and I was wondering how best to get offline GPS co-ordinates in lat and long. I've been doing some digging around and the code below seems to work. I pull the lat, long and accuracy result from this code into a separate field on my form.
What I am not sure about is how to pull in a timestamp so that I can be assured the reading is current and not something cached on the device. The currency and reliability of the coordinates is very important to me.
Any help at all on this would be marvellous!!
Thanks, Angela
<!DOCTYPE html>
<html>
<body>
<p>Get your latitude and longitude (test this to ensure it works when out of coverage)</p>
<button onclick="getLocation()">Get your coordinates</button>
<p id="demo"></p>
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
"<br>Accuracy: " + position.coords.accuracy + '<br />'
}
function showPosition(position) {
var latlon = position.coords.latitude + "," + position.coords.longitude +", Accuracy " + position.coords.accuracy;
$('input[name="coords"]').val(latlon).trigger('input');
}
</script>
</body>
</html>
getCurrentPosition accepts a second parameter, PositionOptions. There are a few options you can experiment with to achieve desired results, but specifically you'll want to use maximumAge and enableHighAccuracy. To ensure uncached results:
navigator.geolocation.getCurrentPosition(function(pos){
console.log('Got position', pos);
}, {
// can be `0` = uncached, any number in milliseconds,
// or `Infinity` which will only retrieve cached results
maximumAge: 0,
// may take longer, but browser will do everything possible
// to get the most accurate position
enableHighAccuracy: true
});
It's also worth noting the returned Position comes with an accuracy property, which returns a positive double indicating the accuracy of your lat and long in meters. Depending on the use case, you may want to require a certain accuracy threshold for users to interact with your app. You can see the full spec here.

Extract duration from Google-distance url

I'm in the middle of developping a map app that enables user to send duration data that it takes him to get to another place, to the database (MySQL) , for this reason I tried to extract the double value of duration directely from url as it's showing in the method below :
#Override
public void setDouble(String result) {
String res[]=result.split(",");
Double min=Double.parseDouble(res[0])/60;
int dist=Integer.parseInt(res[1])/1000;
Duree.setText("Duration= " + (int) (min / 60) + " hr " + (int) (min % 60) + " mins");
Distance.setText("Distance= " + dist + " kilometers");
}
In this method it worked, but when I tried to do it like this :
url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins="+latt+","+lngg+"&destinations="+lt+","+lg+"&mode=driving&language=fr-FR&avoid=tolls&key=API_KEY";
String res[]=url.split(",");
Double duration=Double.parseDouble(res[0])/60;
It showed me that it's not a valid double value, knowing that I need to send this value when I click a button showed on a popup window after marker click (So the problem of inner class is posed).
Can you help me know what is the right way to do it ,if that is possible !
Don't expect your first result-field contains the duration but make your parsing a little more intelligent. Use, by example, the org.json library (introduction on json
Following code snippet should help a little:
LOGGER.debug("---google duration in seconds = {}", jsonElement.opt("duration") == null ? 0 : jsonElement.getJSONObject("duration").get("value"));
transportInfo.setDuration(jsonElement.opt("duration") == null ? 0 : (Integer) jsonElement.getJSONObject("duration").get("value"));
And, btw, I would recommend removing your API key ASAP from your post .... Be aware this key could be used by other people.

Get precise Android GPS-Location in Python

I try to obtain the GPS-Location of my Android Phone in Python (using QPython3 app). This kind of works, but it seems there are several LocationProviders in Android:
gps: pure gps location, slow, energy consuming, but very accurate,
and exactly what I need.
network: mix of gps and wifi/cell locating, faster, but less accurate
passive: like above but completely without using gps
Problem:
When I run my script (below) I only get my location provided by "network"
wich is not accurate enough.
But I can't find a way to force a specific LocationProvider.
Code:
# import needed modules
import android
import time
import sys, select, os #for loop exit
#Initiate android-module
droid = android.Android()
#notify me
droid.makeToast("fetching GPS data")
print("start gps-sensor...")
droid.startLocating()
while True:
#exit loop hook
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
line = input()
print("exit endless loop...")
break
#wait for location-event
event = droid.eventWaitFor('location',10000).result
if event['name'] == "location":
try:
#try to get gps location data
timestamp = repr(event['data']['gps']['time'])
longitude = repr(event['data']['gps']['longitude'])
latitude = repr(event['data']['gps']['latitude'])
altitude = repr(event['data']['gps']['altitude'])
speed = repr(event['data']['gps']['speed'])
accuracy = repr(event['data']['gps']['accuracy'])
loctype = "gps"
except KeyError:
#if no gps data, get the network location instead (inaccurate)
timestamp = repr(event['data']['network']['time'])
longitude = repr(event['data']['network']['longitude'])
latitude = repr(event['data']['network']['latitude'])
altitude = repr(event['data']['network']['altitude'])
speed = repr(event['data']['network']['speed'])
accuracy = repr(event['data']['network']['accuracy'])
loctype = "net"
data = loctype + ";" + timestamp + ";" + longitude + ";" + latitude + ";" + altitude + ";" + speed + ";" + accuracy
print(data) #logging
time.sleep(5) #wait for 5 seconds
print("stop gps-sensor...")
droid.stopLocating()
Sample Output (fake coordinates):
net;1429704519675;37.235065;-115.811117;0;0;23
net;1429704519675;37.235065;-115.811117;0;0;23
net;1429704519675;37.235065;-115.811117;0;0;23
Summarization:
How do I get a precise GPS location in Android using Python?
Thanks in advance everyone!
EDIT: already tested:
inside / outside
enabled / disabled
WiFi GPS enabled (before running script)
I had the same problem. You Can do something Like this if you want to enforce GPS as LocationProvider
import android, time
droid = android.Android()
droid.startLocating()
print('reading GPS ...')
event=droid.eventWaitFor('location', 10000)
while 1:
try :
provider = event.result['data']['gps']['provider']
if provider == 'gps':
lat = str(event['data']['gps']['latitude'])
lng = str(event['data']['gps']['longitude'])
latlng = 'lat: ' + lat + ' lng: ' + lng
print(latlng)
break
else: continue
except KeyError:
continue
I was trying to do something like this today and I had a similar problem. I was getting the same output over and over again. Long story short, I discovered this. Putting this in at the bottom of the loop should solve the problem.
droid.eventClearBuffer()
If you look at the original post sample output, you will notice that the time stamps are all the same. Clearing the buffer resets the object returned by the 'location' event.
droid = android.Android()
droid.startLocating(0, 0)
event = droid.eventWait(1000).result
if event['name'] == "location":
print(event['data']['gps'])
droid.stopLocating()

How can I get exact GPS location with AIR Geolocation API?

How can I get the exact Latitude and Longitude? I only get whole numbers. From my understanding, in order to get down to the meter I need to get down to 5 decimal places. I have tried the horizontal and vertical accuracy but they don't match my phones GPS reading.
How can I get an exact GPS reading with Geolocation API, Down to the meter?
here is my code
var my_geo:Geolocation = new Geolocation();
my_geo.setRequestedUpdateInterval(2000);
my_geo.addEventListener(GeolocationEvent.UPDATE, onGeoUpdate);
function onGeoUpdate(e:GeolocationEvent):void
{
gpsLat1 = (e.latitude);
gpsLon1 = (e.longitude);
gpsHeading = (e.heading);
gpsHorAcc = (e.horizontalAccuracy);
gpsVerAcc = (e.verticalAccuracy);
gpsCheck = 2;
my_txt.text = "My Latitude is "+ gpsLat1 + " and my Longitude is "+ gpsLon1 + " Bearing is " + gpsHeading+ " HorAcc "+ gpsHorAcc+ " VertAcc "+gpsVerAcc;
}
Make sure your variables (gpsLat1, gpsLon1, gpsHeading, etc.) are of type Number and not a uint or int. Unsigned Integers and Integers only allow for whole numbers, whereas Number is the equivalent of float in most other languages (and allows for incredibly larger values, as well). If you save a decimal to an integer, it is rounded off/floored (I can't remember which), which sounds exactly like the problem you are having.
Alternatively, the API is restricted by the hardware you are testing on. If the hardware only returns a certain value for GPS coordinates, AIR cannot be any more precise. Odds are this is not the issue since a whole lat long point can be miles and miles in distance, meaning any device with that inaccurate of a GPS chip is absolutely useless.
Try this:
function onGeoUpdate(e:GeolocationEvent):void
{
gpsLat1 = (e.latitude.toString());
gpsLon1 = (e.longitude.toString());
gpsHeading = (e.heading.toString());
gpsHorAcc = (e.horizontalAccuracy.toString());
gpsVerAcc = (e.verticalAccuracy.toString());
gpsCheck = 2;
my_txt.text = "My Latitude is "+ gpsLat1 + " and my Longitude is "+ gpsLon1 + " Bearing is " + gpsHeading+ " HorAcc "+ gpsHorAcc+ " VertAcc "+gpsVerAcc;
}

Categories

Resources