Has anyone out there had to deal with and managed to find a viable workaround for the Firefox 5 geolocation issue I posted in the following bug report. It's easier to link to the report than re-describe it here.
https://bugzilla.mozilla.org/show_bug.cgi?id=675533
Surely I'm not the only one on the planet this has bitten.
This doesn't really solve the root of your problem but my strategy for handling this is setting a default location point that I use right away (not waiting for the geolocation question to be answered).
If I get a location from the user, I just change it to the new location. If I get a rejection or no answer at all, I just stay on the default location.
It's also my experience that a desktop client (in my case Firefox on a stationary Windows computer) takes much longer to respond than a mobile client (in my case Safari on iPhone). I was forced to set the timeout to 10 seconds (10000) to give the desktop client enough time to respond. So if you have a map, initializing it and centering on a default location directly will give the user a map on the screen much faster than if you have to wait for a response.
Good luck with your positioning project!
I might be a bit late but hope I can help others.
My workaround is based on a delayed call. If there is no fix when the delayed call is fires, I become suspicious :)
var timeIsPassig = false;
function anyThing(){
timeIsPassig = true;
setTimeout(
function(){
if (timeIsPassig) {
timeIsPassig = false;
console.log("Waiting too much... Or did you say not now? :-P");
}
},
10000
);
navigator.geolocation.getCurrentPosition(
function (pos) {timeIsPassig = false; /* rest of positioning*/},
function (err) {timeIsPassig = false; /* rest of error handling*/},
{maximumAge: 30000, timeout: 10000, enableHighAccuracy: true}
)
}
Related
I am writing an application for my own purposes that aims to get play pause events no matter what is going on in the system. I have gotten this much working
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("Play Pause Command")
return .success
}
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("NextTrackCommand")
return .success
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("previousTrackCommand")
return .success
}
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("playCommand")
return .success
}
MPNowPlayingInfoCenter.default().playbackState = .playing
Most of those methods are there because apparently you will not get any notifications without having nextTrackCommand or previousTrackCommand or playCommand implemented.
Anyways my one issue is that as soon as you open another application that uses audio these event handlers stop getting called and I cant find a way to detect and fix this.
I would normally try doing AVAudioSession things to state this as a background application however that does not seem to work. Any ideas on how I can get playpause events no matter what state the system is in?
I would like to be able to always listen for these events OR get an indication of when someone else has taken control of the audio? Perhaps even be able to re-subscribe to these play pause events.
There's an internal queue in the system which contains all the audio event subscribers. Other applications get on top of it when you start using them.
I would like to be able to always listen for these events
There's no API for that but there's a dirty workaround. If I understand your issue correctly, this snippet:
MPNowPlayingInfoCenter.default().playbackState = .paused
MPNowPlayingInfoCenter.default().playbackState = .playing
must do the trick for you if you run it in a loop somewhere in your application.
Note that this is not 100% reliable because:
If an event is generated before two subsequent playbackState state changes right after you've switched to a different application, it would still be catched by the application in the active window;
If another application is doing the same thing, there would be a constant race condition in the queue, with unpredictable outcome.
References:
Documentation for playbackState is here;
See also a similar question;
See also a bug report for mpv with a similar
issue (a pre-MPRemoteCommandCenter one, but still very valuable)
OR get an indication of when someone else has taken control of the audio
As far as I know there's no public API for this in macOS.
This is on iOS 12.1.4 on an iPhone 6s. Usually Geolocation.GetLastKnownLocationAsync() works but sometimes it doesn't. It's the exact same code but if I sit here and press my "get latitude and longitude" button over and over eventually Geolocation.GetLastKnownLocationAsync() spits out a null.
Do you know why this happens and how I might handle it? Perhaps put it in a loop that tries ten times, waiting a second between each try?
var location = await Essentials.Geolocation.GetLastKnownLocationAsync(); // works most of the time but sometimes it doesn't work.
This is my proposed work around:
Essentials.Location location = null;
for(var i = 0; i < 10; i++)
{
location = await Essentials.Geolocation.GetLastKnownLocationAsync();
if(location == null)
{
Thread.Sleep(1000);
}
else
{
break;
}
}
First, it is really bad practice to use Thread.Sleep (unless you are not on the main/UI loop) as you are hanging the run loop, if you really need a delay, use await Task.Delay(.... Also CLLocationManager on iOS is running on the main loop and if you are blocking it, the message pump is hung and the location manager manager can not report back to the app.
"Spamming" CLLocationManager.Location (which Essentials is using on iOS) can (and will) result in null returns due to OS rate limiting updates (mainly a battery conservation measure) and if the OS is powering up the GPS radio to update its location, this method will timeout on from the OS, thus report nil back to GetLastKnownLocationAsync and thus you get a return of null.
CLLocationManager.Location on iOS is meant for a quick low-power return from the OS to app as is updated upon app launch, device reboot, etc... not every time you call it.
You can get the last known location of the device by calling the GetLastKnownLocationAsync method. This is often faster then doing a full query, but can be less accurate.
Otherwise you should be using GetLocationAsync in order to do a full GPS power up to obtain an updated accurate location.
To query the current device's location coordinates, the GetLocationAsync can be used. It is best to pass in a full GeolocationRequest and CancellationToken since it may take some time to get the device's location.
Typically I recommend using GetLastKnownLocationAsync as a quick way to get the general area of the user knowing that this might also return null. Then proceed to do a GetLocationAsync (passing both a GeolocationRequest and CancellationToken instance) in the background and update the app accordingly upon the more accurate and recent position.
re: https://learn.microsoft.com/en-us/xamarin/essentials/geolocation?tabs=ios
Today, I had to restart my browser due to some issue with an extension. What I found when I restarted it, was that my browser (Chromium) automatically updated to a new version that doesn't allow synchronous AJAX-requests anymore. Quote:
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/.
I need synchronous AJAX-requests for my node.js applications to work though, as they store and load data from disk through a server utilizing fopen. I found this to be a very simplistic and effective way of doing things, very handy in the creation of little hobby projects and editors... Is there a way to re-enable synchronous XMLHttpRequests in Chrome/Chromium?
This answer has been edited.
Short answer:
They don't want sync on the main thread.
The solution is simple for new browsers that support threads/web workers:
var foo = new Worker("scriptWithSyncRequests.js")
Neither DOM nor global vairables aren't going to be visible within a worker but encapsulation of multiple synchronous requests is going to be really easy.
Alternative solution is to switch to async but to use browser localStorage along with JSON.stringify as a medium. You might be able to mock localStorage if you allowed to do some IO.
http://caniuse.com/#search=localstorage
Just for fun, there are alternative hacks if we want to restrict our self using only sync:
It is tempting to use setTimeout because one might think it is a good way to encapsulate synchronous requests together. Sadly, there is a gotcha. Async in javascript doesn't mean it gets to run in its own thread. Async is likely postponing the call, waiting for others to finish. Lucky for us there is light at the end of the tunnel because it is likely you can use xhttp.timeout along with xhttp.ontimeout to recover. See Timeout XMLHttpRequest
This means we can implement tiny version of a schedular that handles failed request and allocates time to try again or report error.
// The basic idea.
function runSchedular(s)
{
setTimeout(function() {
if (s.ptr < callQueue.length) {
// Handles rescheduling if needed by pushing the que.
// Remember to set time for xhttp.timeout.
// Use xhttp.ontimeout to set default return value for failure.
// The pushed function might do something like: (in pesudo)
// if !d1
// d1 = get(http...?query);
// if !d2
// d2 = get(http...?query);
// if (!d1) {pushQue tryAgainLater}
// if (!d2) {pushQue tryAgainLater}
// if (d1 && d2) {pushQue handleData}
s = s.callQueue[s.ptr++](s);
} else {
// Clear the que when there is nothing more to do.
s.ptr = 0;
s.callQueue = [];
// You could implement an idle counter and increase this value to free
// CPU time.
s.t = 200;
}
runSchedular(s);
}, s.t);
}
Doesn't "deprecated" mean that it's available, but won't be forever. (I read elsewhere that it won't be going away for a number of years.) If so, and this is for hobby projects, then perhaps you could use async: false for now as a quick way to get the job done?
For example, someone enters a comment onto a page — how would I cause all other browsers on that page to say reload it to receive the new update? Specifically I am looking at 'dynamically' updating NOT 'periodically' updating. Minimal bandwidth for maximal efficiency.
I am no expert programmer — please simplify the solution if possible.
There is HTTP Server Push technology, but from what I heared, I would always prefer polling (consumes less server resources and is more compatible).
You could use websockets, which are part of HTML5.
var socket = new WebSocket("ws://example.com:8000/websocket.php");
socket.onmessage = function(msg) {
// update content here
alert("New content:" + msg);
}
However, you would have to have a server-side technology that supports it.
Using Windows 2008, C#, Firefox 3.5.1, Selenium RC (v1.0.1)
When it works, this code executes very quickly and the page loads within .5 seconds.
However, the session always seems to fail after 3 - 5 iterations. The open command will cause a window to be spawned, but no page to be loaded. Eventually a timeout exception is returned. The page has not actually timed out. Instead, it is as though the request for a URL has never reached the browser window.
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
var s = new DefaultSelenium("localhost", 4444, "firefox", "http://my.server");
s.Start();
s.SetSpeed("300");
s.Open("/");
s.WaitForPageToLoad("30000");
s.Type("//input[contains(#id, '_username')]", "my.test");
s.Type("//input[contains(#id, '_password')]", "password");
s.Stop();
}
}
}
I have a similar set up (Firefox 3.6.15, Selenium RC 1.0.1, but on WinXP and using the Python libraries) and I am working with a couple of sites - one site is naturally prone to timeouts in normal use (e.g. by a human user) whereas the others typically are not. Those that aren't appear a little slower but the one that is prone to timeouts is significantly slower when run via RC than by a person - it won't always timeout but the incidence is much much more common.
My limited mental model for this is that somehow the extra steps RC is doing (communicating with the browser, checking what it sees in the returned pages etc etc) are somehow adding a bit to each step of the page loads and then at some point they will push it over the edge. Obviously this is overly simplified, I just haven't had time to properly investigate.
Also, I do tend to notice that the problem gets worse over time, which fits a little with what the OP has seen (i.e. working the first time but not after 3 - 5 attempts). Often a reboot seems to fix the issues, but without proper investigation I can't tell why this helps, perhaps it is somehow freeing up memory (the machine is used for other things), getting allocated to a different one of our company's proxies or something else I haven't considered.
So... not much of a full answer here (a comment would have been more appropriate, but my login isn't able to yet), but at least it reinforces that you're not the only one. Periodic restarts are an annoying thing to need to do, but in the absence of any smarter analysis and answers, maybe they'd be worth a shot?
I was facing the same problem .This is because open method of DefaultSelenium has timeout of 30000ms, so it waits for 30s for your page to load. You can try this trivial solution.
//selenium is DefaultSelenium instance as private member of the class
boolean serverStartTry = false;
int tryCount =1;
while((!serverStartTry) && tryCount <= Constants.maxServerTries){
try{
this.selenium.open(ReadConFile.readcoFile("pageName"));
System.out.println("Server started in try no: "+tryCount);
serverStartTry =true;
}catch (SeleniumException e) {
System.out.println("Server start try no: "+tryCount );
System.out.println("Server Start Try: "+ serverStartTry);
serverStartTry = false;
tryCount++;
}
}
if(!serverStartTry){
System.out.println("Server Not started, no. of attempts made: "+tryCount);
System.exit(0);
}
I've solved using:
selenium.setTimeout("60000");
before open instruction.