navigator.geolocation.getCurrentPosition() never returns in WebView on Android

后端 未结 8 1246
萌比男神i
萌比男神i 2021-02-18 16:27

I am trying to access the HTML Geolocation API available in Android WebView (using SDK version 24).

The main problem is that the call to navigator.geolocat

8条回答
  •  迷失自我
    2021-02-18 17:05

    Try with options to set timeout (source):

    var options = {
        enableHighAccuracy: true,
        timeout: 10000,
        maximumAge: 0
    };
    
    navigator.geolocation.getCurrentPosition(success, error, options);
    

    If it fails then try to override getCurrentPosition (source):

    (function() {
    
    if (navigator.geolocation) {
        function PositionError(code, message) {
            this.code = code;
            this.message = message;
        }
    
        PositionError.PERMISSION_DENIED = 1;
        PositionError.POSITION_UNAVAILABLE = 2;
        PositionError.TIMEOUT = 3;
        PositionError.prototype = new Error();
    
        navigator.geolocation._getCurrentPosition = navigator.geolocation.getCurrentPosition;
    
        navigator.geolocation.getCurrentPosition = function(success, failure, options) {
            var successHandler = function(position) {
                if ((position.coords.latitude == 0 && position.coords.longitude == 0) ||
                    (position.coords.latitude == 37.38600158691406 && position.coords.longitude == -122.08200073242188)) 
                    return failureHandler(new PositionError(PositionError.POSITION_UNAVAILABLE, 'Position unavailable')); 
    
                failureHandler = function() {};
                success(position);
            }
    
            var failureHandler = function(error) {
                failureHandler = function() {};
                failure(error);
            }
    
            navigator.geolocation._getCurrentPosition(successHandler, failureHandler, options);
    
            window.setTimeout(function() { failureHandler(new PositionError(PositionError.TIMEOUT, 'Timed out')) }, 10000);
        }
    }
    })();
    

    As a third option annotate with @JavascriptInterface (source) in EmbeddedChromeClient

    Also add at the proper place in your code:

    mWebSettings.setJavaScriptEnabled(true);
    //...
    mWebSettings.setSupportZoom(true);
    webView.addJavascriptInterface(new EmbeddedChromeClient(webView), "injectedObject");
    webView.loadData("html here", "text/html", null);
    

    The last option is just to use tags in html, load the html from disk storage, replace tags in the calling function, load the html/string in the webView. I have used this approach before in Android when positioning frustrated me too much. Then you don't have to worry about https either.

提交回复
热议问题