1

I have a WebView which pulls up a web page which uses the Google Maps API, and I have this object called MapsBase which handles the map stuff. Inside the MapsBase init() I have:

window.addEventListener('blur', (function (obj) {
    return function (evt) { obj.Pause(); };
})(this), true);
window.addEventListener('focus', (function (obj) {
    return function (evt) { obj.Resume();};
})(this), true);

Which acts on these functions:

MapsBase.prototype.Pause = function () {
    //Chrome bug - focus and blur events are called twice.
    if (this.isPaused) {
        return;
    }
    if (window['DEBUG']){window.console.log('MapsBase.prototype.Pause()');}
    this.isPaused = true;
    this.geolocationMarker.setMap(null);
};

MapsBase.prototype.Resume = function () {
    if (this.isPaused) { //Chrome bug - focus and blur events are called twice.
        if (window['DEBUG']){window.console.log('MapsBase.prototype.Resume()');}
        this.isPaused = false;
        this.geolocationMarker.setMap(this.map);
    }
};

On the Android side, I have my WebView (extends Fragment), which uses this in onStart():

WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setGeolocationEnabled(true);
settings.setGeolocationDatabasePath(context.getFilesDir().getPath());

and has this as the onPause method:

@Override
public void onPause(){
    if (MainActivity.DEV_MODE) {  Log.i("WebFragment","onPause - dispatching the 'blur' event"); }
webView.getSettings().setGeolocationEnabled(false);
    super.onPause();
}

It appears that all the events are firing as planned. When I monitor the debug output on my Nexus 4, I see that the onPause method is firing and dispatching the 'blur' event, but the geolocation is still active (showing in the notification area).

tl;dr:

Is there any way to force the WebView to give up geolocation?

Edit:

It appears that the geolocation is deactivated when using the back button (system) to back out of the webview, but not when simply navigating away using the Navigation Drawer navigation I have going, like if I were to open the drawer and go to a totally different section of the app. It also happens if I just press the home button (the system "home" to go back to the launcher).

Here's the log output when I navigate to a different part of the app using the Navigation Drawer (after this point, the geolocation is still active): enter image description here

Edit 2:

There have been many questions on SO regarding switching GPS on/off. In particular, one which seems to be relevant is the question Switch off GPS programatically. Both the question and answer selected seem to fit what I'm looking for, but just seems like it's overkill. I don't have a LocationListener, and in order to get one, I'd need to follow the Location Strategies guide.

It seems like setting geolocation to be disabled through the WebView should do the trick (like what I'm doing in onPause), but it doesn't.

The other option I've seen on SO is simply disabling GPS altogether for the app, which isn't possible except through exploitation of a security hole which has already been fixed.

is this a bug in the WebView code?

Edit 3:

I found the fix to my immediate problem, and it was an error in my JavaScript. The setMap function for the geolocation marker wasn't clearing the callback functions that were set up for the map.

As for the bigger issue at hand, Why does the web page Geolocation overrule the WebView geolocation settings? It turns out that this this was a bug that has been marked as "fixed" (at least for an Activity). I suspect that this is a regression which shows up when the WebView is run within a Fragment.

Community
  • 1
  • 1
Kyle Falconer
  • 8,302
  • 6
  • 48
  • 68
  • @mohitum007 the root cause (the bug) remains unfixed and I just checked again two days ago. My immediate solution (workaround) came from making sure all the event listeners and callback functions were cleared from the web page. – Kyle Falconer May 02 '14 at 18:05

1 Answers1

0

I know this is way too late, but for future reference this could be used:

@Override
public void onPause(){
    this.webView.onPause();
    this.webView.pauseTimers();
    super.onPause();
}

In the webview docs:

public void onPause ()

Does a best-effort attempt to pause any processing that can be paused safely, such as animations and geolocation. Note that this call does not pause JavaScript. To pause JavaScript globally, use pauseTimers(). To resume WebView, call onResume().

Community
  • 1
  • 1
riadrifai
  • 1,108
  • 2
  • 13
  • 26