iOS6 Mobile Safari: Accuracy and update periods of geolocation.watchPosition - javascript

I'm facing a strange behavior on mobile Safari on iPhone4 and iPhone5 on iOS6.
What I want to do
Tracking the user's location in the browser with high accuracy, using
geolocation.watchPosition({ enableHighAccuracy: true, maximumAge: 0, callback })
Problem I'm facing
Normally, when the device is outside, under clear sky and moving, the accuracy und the update period of the GPS positions is very good.
The coords object passed to the callback has an accuracy of 5 meters, a correct heading value is given and when moving the callback gets fired at least every 500ms.
But: Sometimes the watched position never gets accurate, even though I test it under the same conditions (as far as possible).
Also, the update period is much longer, almost 30 seconds.
Basically, in this cases, the HTML geolocation is not useable for the accurate tracking of a position.
Observations
This seems to happen, when the GPS-Sensor is not on "Hot-Standby", I mean it was not used for some time (not sure how long) by another native app.
Reloading the page, re-allowing the GPS access and re-initializing the watchPosition does not change anything, still bad accuracy and slow updates.
Changing the options passed to watchPosition does not seem to do anything.
Manual fix 1:
Close Safari
Open another native app like Maps or GMaps
Determine the position in the native app
Open Safari
GPS position is immediately accurate, following position updates are fired again in 500ms periods and are very accurate as well (no reload needed).
Manual fix 2:
Close Safari
Open settings panel
Disable Wi-Fi
Open Safari
Again, problem fixed (without a reload)
Conclusion
When the problem occured, I looked into the coords object of the callback and detected the following:
Even though the passed location is far away from the real position of the device (> 1km), the accuracy passed is much smaller (very often at 165 meters). The heading is never given.
When WiFi on iPhone is disabled, there is a hint in the settings panel that says enabling WiFi will enhance the accuracy of determining your location (because of AGPS which is supported by a datase of geocoded WiFi networks). But as far as I can see this is not true if you want to use GPS in mobile safari. In fact, it does the opposite.
It seems to me that mobile safari does something like this to determine the location:
If GPS is already activated/in use on the device, it uses the GPS sensor (fast and accurate position updates)
If GPS wasn't active before and WiFi is enabled, the device only uses its WiFi database to get the location. (very slow updates, not accurate). It just updates from one WiFi location to another. You can see this very clearly e.g. if you drive on federal roads, as your location mostly get mapped to the next residential area.
Only if GPS wasn't active before and WiFi is disabled mobile safari will use the GPS to determine the location of the device (again, fast and accurate).
Question
Can anybody confirm my problem and my observations?
I worked with the geolocation in earlier iOS versions but never faced this problem before.
Is it a known bug for mobile safari, any chance that this will be fixed? Or am I just missing a better configuration of the watchPosition to get better results?

A lot of people have described similar problems including myself. I have described my problems on page 5 and onwards (as alstorp) in this discussion https://discussions.apple.com/thread/4313850?start=45&tstart=0
Read and see if it matches your problem.
The problem is that, as far as I know, Apple has not confirmed this. Are they working on fixing it? Is it really on their side? Is it really a bug? Therefore we do not know when/if it will be fixed...
Is there anyone out there that does NOT have problem with browser based geolocation in iOS 6? (even after multiple tests in different situations).
Have you tested your fixes extensively? My experience is that this type of fixes helps in some cases but not all the time (or for long periods). It would be really interesting if they work reliably for you...
(also check IOS6 geolocation watchPosition Callbacks fail
iOS 6 breaks GeoLocation in webapps (apple-mobile-web-app-capable) )

Can anybody confirm my problem and my observations? I worked with the geolocation in earlier iOS versions but never faced this problem before.
I tried watchPosition(onGeoSuccess,onGeoFail,{enableHighAccuracy:true}); in my web app using my iPhone (iOS 7.0.2).
With WiFi on accuracy was really bad, sometimes a mile off. With WiFi off accuracy was near perfect, with an occasional discrepancy of a couple hundred feet.
I have yet to test to see if helps to leave the GPS running between capture points, or if it's better to leave it off until you're at the next capture point and let the watchPosition() function settle.

Related

Workaround for bug on Chromium WebView about high load causing partial rendering on canvas

I found [1] this issue on newest WebView of Chrome. To produce it you need three things:
You have updated WebView to version from 15.11.2021
HardwareAcceleration in AndroidManifest is set true
When you heavily give stuff to render for webview, you start to see missing content on screen.
My technology stack uses a Openlayers map inside app that is actually a small website packed with Cordova, which is the component that uses the WebView.
By heavy use I mean the map has to have many layers of map data on for rendering and I have to make some maneavours moving the map and making it to start loading next rendered content before the previous one is completed.
At first time I open the map after installation, the map works ok with heavy load. Issue starts when I kill the app and login again and make the heavy movements when the app tries to render the first time. After that the map does not render content as a whole, some tiles and map menus come only partially.
The behavior continues even when I click off some map layers, and when there is very little of them anymore, the issue settles down. Interesting point is also, there is no single point where the load is enough to trigger the issue or settle down, at least the point is different going to each direction.
There is a warning message, that comes to logcat only when the issue is present:
chromium: [ERROR:tile_manager.cc(821)] WARNING: tile memory limits exceeded, some content may not draw
and I can observe it to be coming along same lines the 15.11.2021 version update has removed some "useless data" [2]. I am not 100% sure if these two things are related, but I have realized the versions before that particular update work just fine with my app (I removed updates from WebView in Google Play).
There are currently three workarounds:
Do not use map layers that are too heavy and trigger the issue (makes bad for our app user experience by hiding crucial information from user)
Remove webview updates from PlayStore (I personally tested that, overnight the system updated the broken version back, hard to communicate to end users).
Not to use hardware acceleration. (Other parts of the app get useless, too slow behavior makes end users angry).
As you observe none of these is working well. I believe that this same behavior is seen by other WebView heavy users too, so I opened this question with only one main question:
Meanwhile my bug report is advancing in Google, what could I do meanwhile to overcome the issue?
Sources:
[1] https://bugs.chromium.org/p/chromium/issues/detail?id=1274482
[2] https://chromium.googlesource.com/chromium/src/+/a0994781ea666d9b630b6478206ac429ed8444d1%5E%21/#F0

Canvas not working properly if developer console is active

A few days ago, I was wondering about why my canvas is not working properly. I'm using szimek's library to create signatures and sometimes those pen strokes looked a bit crazy. I also tested on Edge (which ended in the same result as Chrome) and TOR (worked as it should).
Yesterday, I found the solution why this happens randomly. My strokes look crazy during the usage of the browsers developer console when it's open. If it's closed, they're looking normally (when drawing again).
Does anyone know why this happened or is it caused by it's core engines?
Here's an example of what I mean:
Thank you.
This happens because in Chromium (and in Gecko), as per specs recommendations, UI events like mousemove or pointermove are throttled to the frame refresh rate of the monitor.
However, in Chromium only and for whatever reason, when the dev tools are open, they emit the raw events...
So when dev tools are closed, even though the hardware pointer (e.g mouse) did emit more events, these have been coalesced into a single pointermove event, which may draw lines smoother to the eye since each point have been averaged, but you actually received less data.
You can retrieve the list of raw events from the pointermove event's getCoallescedEvents, as exposed in this other answer of mine, and from these you could also build up the coalescing logic yourself if needed (using requestAnimationFrame() as a throttler, that's exactly what Chromium does).
As to why Chromium does disable the coalescing when dev-tools are open... that's still a mystery for me, but I never got enough incentive to look this up.

Test for memory issues with website on a device?

I'm having a issue which is hard to debug. I'm using a Javascript library (the JQuery Flexslider plugin) in a number of different places on my site. It's all working fine except for one particular phone where it doesn't work and slows down everything on the page.
So far, I've only seen it happen on this one device. Other devices of the same type do not have the issue. This person has an iOS that's a few versions out of date and not much memory, so I think it's a memory issue.
An old hack was to move the carousel element that has the issue on the page with Javascript, but I want to find and fix the root issue.
How can I start debugging this? I'm not sure how to test for a memory issue on a device.
If you're on a Mac, then you can plug in and use remote debugging via Safari, where you'll have access to the tools, including the profiler (not sure the state of Safari support in Windows). There are numerous resources for showing how to remotely debug a device, unless it is a really old version of iOS you should be fine, you’ll have to enable the develop menu via settings but after that its plain sailing if you know your debugging tools.
I'd agree that it doesnt really sound like a memory issue, although jQuery tends to be hungry in that respect, I dont know the plugin in question but the quality of plugins is hugely variable in jQuery-land. Old phones and old versions of jQuery certainly never played well together.
When you say one phone, you mean one type of phone + iOS version? The question isnt clear, its almost reads like you have 2 identical phones/os's where 1 works and 1 does not.
If you use Chrome you can use the Heap profiler
First open your developer tool and start recording.
Next start using your page and try to replicate your issue, stop recording and review the stats.
This is likely not a memory issue, but a cpu issue. The way jQuery does animation is processor constrained on older dvices. Factors that are easiest to handle include:
size of the page (html length and complexity)
animation steps, length, and complexity
You have a couple of options here, but the simple answer is you are asking too much of the older processor. Assuming you are using this plugin http://www.woothemes.com/flexslider/ you could try disabling or simplifying some of the transition effects. animation and animationSpeed would be the first I would suggest.
If you are interested in not changing the experience for most users you could consider tying into the start and end functions on the callback api and checking the time it took to perform the first transition, then reinitialize a simpler version of the slideshow for that device.
The hard thing here is there isn't really a right answer. If one of the above options doesn't fix it you're likely looking at choosing/building a different slideshow, degrading the experience for everyone, or determining the best way you feel comfortable with choosing who gets the degraded experience.

How can I identify usage of hardware vs soft keyboard in a hybrid tablet?

Problem:
I have a small group of roughly 90 users which is extremely important, so when one or two of these business customers desire the UI changed in their web app, they usually get development resources dedicated. However, it's important for us to understand exactly how the application is being used by the group as a whole because this group tends to have strong personal views on how their UI should look and they all use the app differently. I'm having the most trouble with identification of their usage of hardware vs soft keyboard. Optimally I'm looking for an answer as simple as, "use the new Window.TabletMode == true!" I don't think that simple answer exists.
Research:
SO question Detect virtual keyboard vs. hardware keyboard is the only significantly similar question I see but it focuses half of its time on using a JavaScript keyboard to replace the soft keyboard, so the answers talk about how to make the keyboard specific to numbers, dates etc. Additionally, he's looking for cross-browser solutions where I need only IE11+ support. Finally, I can depend on the hardware keyboard being docked and a specific brand (Dell). Finally, I can depend upon Windows/IE11, so there could be other avenues of approach compared to this 3-year-old question. My use of a hybrid tablet also makes the approaches of capability checks useless since I already knwo all the capabilities (touch, etc) are already available on the device.
I could check the Registry for the UI setting, but I really need to stick to JavaScript or something similar.
Android has undocumented but known events which indicate showing and hiding of the keyboard. However, none of the users will be using Android.
IE should receive a WM_SETTINGCHANGE message when the change occurs, but I'm unable to determine if this is made available to a JavaScript API. I'm thinking it would be a message far more specific (if any), so I can't find anything with this search term and JavaScript.
Code:
From W3Schools,
The window.orientation property returns 0 for portrait and 90 or -90 for landscape view.
Combined with window.innerHeight, I could use something like...
var portrait;
$(window).on("orientationchange",function(event){
if (event.orientation == 0)
{
portrait = true;
}
else //if not, it's landscape
{
portrait = false;
}
});
Then I would use window.innerHeight in combination with the value of portrait to determine if the width to height ratio looks like I have a keyboard open. This approach really might work in fullscreen considering my fairly narrow constraints, but what if the browser isn't fullscreen? I'm sure there are plenty of other reasons to not write a hacky ratio calculation for this. Additionally, my greatest desire would, of course, be to do this with any browser and any screen size.
These things I can handle: I'd need to set variables on the loading of the document and work out a way to determine when the typing becomes relevant. I might need to check for some browser capabilities. Perhaps I'd increment counters for typing with and without a hardware keyboard. Once I hit a certain number (let's say 5 keystrokes), I'd send a POST request to my data tracking endpoint to let it know that session 12345 used the soft keyboard (or hard keyboard). Afterwards, I'd unsubscribe from the event handler. However I work this part is of less concern because I don't think I'll get stuck on anything, but I didn't want anyone to spend time on beautification or development of a huge example.
Environment:
Hardware should all be Dell tablet/laptop hybrids (specific model TBD) with IE11+. I hate to make something IE specific, but if it runs on IE11+, it's totally acceptable.
I should be able to pull in any sort of JavaScript libraries suggested, but keep in mind that JQuery 2.2 and Knockout 2.1 are already present, so little "weight" is added for a solution with JQuery usage.
I probably can't get approval to write an application that uses ActiveX or some other heavy handed customized approach that would require installation of a local application because my company has roughly 50,000 users, and a deployment like that for 90 users would be overly complex to maintain.
The screen sizes should all be 11 inches, but I'd be sad to resort to using specific size and resolution because an answer like that would be extremely limited in application for me or future readers.
Impact for Readers:
I'm seeing a move away from Ipads in the medical kiosk / EMR space because Ipads limit a lot of the UI choices in favor of a cohesive experience. Physicians especially will often get attention of high ranking IT leaders if they desire a very specific UI change. Microsoft has tended to allow a lot of non-standard intervention and (more recently) more standard types of intervention in how the browser works. I think a lot of this movement is going to Windows tablets for this reason and also for the reason that many medical groups are heavy on .NET development capability.
Bottom Line: You can't get exactly what you want. With IE11 you actually have a couple other challenges. You can't simply use the Fullscreen API with promise = element.requestFullscreen() because IE will request permission from the user first, and the API lets you check for capability but not state. Also, multiple fullscreen applications can share the desktop in Windows 8 and 8.1, which is a bit counterintuitive.
However, if you can count on the web app probably being fullscreen, your "hackish" JavaScript solution probably is the best answer. Get the initial dimensions when the document loads and compare during key presses. As a side note, keep in mind that the user might not be using the software keypad just because he or she isn't in the dock. The user still needs to explicitly open the software keyboard.
If you had said "Android only", it would be an easy solution, but you already demonstrated you knew that in your question. If you wanted to use a desktop app, there is some MSDN documentation on a hardware token here but again you specified that this wouldn't be simple enough.

How to check if user have zoom from js?

I have specific js (svg drawings, etc) on site and I am not able to create it supercool when user has zoom (can't calculate correct needed values).
So I want to prevent user actions if user zoom value is not 100%.
I tried to use detect-zoom
and this is a bad solution:
For Chrome (os x, Yosemite) have 0.98-1 values while 100% zoom.
For Safari - 0.88
For Firefox - 2.0
And I can say that this is not working sometimes and for Chrome. For example, right after I exit fullscreen mode (videos on site is critical functionality) - library return 1.1 zoom value for one moment.
Also, this is only OS X platform and last versions of browsers. So I guess on other platforms/versions of browsers I can get another different values.
How I should resolve this situation (get correct values). Maybe someone already has a good solution?
Thanks

Categories