2

I've got a WebView that loads a page with location based functionality and a WebChromeClient with onGeolocationPermissionsShowPrompt() overriden. Enabling location for the page works fine when location services are on.

The issue is that if the user's location is turned off I want to prompt them to turn it on, but if it's turned off I never hit onGeolocationPermissionsShowPrompt(). Is this function only called if a location is available?

dwemthy
  • 471
  • 3
  • 9
  • 1
    I am also facing the same issue. Once Location permission is denied by the User, then onGeolocationPermissionsShowPrompt is never called. This will again call, after user uninstalls the app and reinstalls. Can any body can suggest some solution on this? – Rajeev Sahu May 08 '18 at 10:24
  • `callback.invoke` is expected to finish the flow, so you should call `invoke` both permissions revoked or granted. Otherwise, you won't get prompt show again until uninstall or clear app. – cuasodayleo Sep 20 '19 at 11:11

3 Answers3

1

One solution is not to retain the permission (use false as the third parameter in the callback). This can lead to excessive permission asking, so storing the result locally solves that:

class MyWebChromeClient : WebChromeClient() {

    private var givenPermissions: Set<String> = emptySet()

    override fun onGeolocationPermissionsShowPrompt(origin: String, callback: GeolocationPermissions.Callback) {
        val onResult = { allow: Boolean -> callback(origin, allow, false) }
        when {
            origin in givenPermissions -> checkSystemPermission { granted ->
                if (!granted) givenPermissions -= origin
                onResult(granted)
            }
            else -> askForPermission { allow ->
                when (allow) {
                    false -> onResult(false)
                    true -> checkSystemPermission { granted ->
                        if (granted) givenPermissions += origin
                        onResult(granted)
                    }
                }
            }
        }
    }

    private fun askForPermission(callback: (Boolean) -> Unit) {
        // ask for permission
    }

    private fun checkSystemPermission(callback: (Boolean) -> Unit) {
        // check/ask for system permission
    }

}

If the system permission is revoked, the WebChromeClient should be recreated automatically.

petter
  • 1,765
  • 18
  • 22
0

Not sure if this is exactly what you are looking for but I just call a method CheckEnableGPS()

//Method for turning GPS on if it isn't
    private void CheckEnableGPS(){    
    String provider = Settings.Secure.getString(getContentResolver(),      
    Settings.Secure.LOCATION_PROVIDERS_ALLOWED);       
    if(!provider.equals(""))
    {           
      //GPS Enabled        
    Toast.makeText(ShowMapActivity.this, "GPS Enabled: " + provider,          Toast.LENGTH_LONG).show();       
    }
    else
    {        
    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);           startActivity(intent);      
       }   
    }
ZeroSkittles
  • 164
  • 1
  • 3
  • 16
  • I've got a method like that, the issue is I want to run that method when the page in the webview requests the current location, but the WebChromeClient only ever gets the request from the page if location is already on, which defeats the purpose of detecting it. Thanks though. – dwemthy Apr 24 '12 at 20:18
  • Do you also have webView.getSettings().setGeolocationEnabled(true)? – David Chandler Apr 24 '12 at 21:30
0

You need second and third paramater to be false

callback.invoke(origin, false, false);
Ucdemir
  • 2,852
  • 2
  • 26
  • 44