Android WebChromeClient WebView onGeolocationPermissionsShowPrompt永远不会被触发

时间:2013-04-05 18:21:57

标签: android webview gps webchromeclient

我有一个带有WatchPosition调用的网页,可以在常规浏览器中正常使用。但是,请求GPS权限的对话框从未显示何时从WebView使用WebChromeClient加载网页,并且永远不会调用onGeolocationPermissionsShowPrompt。

public class GeoWebChromeClient extends WebChromeClient {
     public void onGeolocationPermissionsShowPrompt(String origin, android.webkit.GeolocationPermissions.Callback callback) {
         Log.d("geolocation permission", "permission >>>"+origin);
         callback.invoke(origin, true, false);
     }
}

 public class GeoWebViewClient extends WebViewClient {

    @Override
    public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();
    }

    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // When user clicks a hyperlink, load in the existing WebView
        view.loadUrl(url);
        return true;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView Browser = (WebView) findViewById(R.id.Browser);

    WebSettings webSettings = Browser.getSettings();

    webSettings.setJavaScriptEnabled(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    webSettings.setAppCacheEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setGeolocationEnabled(true);

    Browser.setWebViewClient(new GeoWebViewClient());
    Browser.setWebChromeClient(new GeoWebChromeClient());

    Browser.loadUrl("http://192.168.1.102/");


}

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

3 个答案:

答案 0 :(得分:6)

onGeolocationShowPrompt实际上并不显示提示本身,它只是在页面请求您的Geolocation时调用的方法。您需要为用户创建自己的提示,如下所示(放在onGeolocatioonShowPrompt方法中):

final boolean remember = true;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Locations");
builder.setMessage(origin + " Would like to use your Current Location").setCancelable(true).setPositiveButton("Allow",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    // origin, allow, remember
                                    callback.invoke(origin, true, remember);
                                }
                            })
                    .setNegativeButton("Don't Allow",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    // origin, allow, remember
                                    callback.invoke(origin, false, remember);
                                }
                            });
AlertDialog alert = builder.create();
alert.show();

答案 1 :(得分:0)

对于像我一样正在寻找如何修复“ onGeolocationPermissionsShowPrompt从未使用过”消息的任何人,这应该有所帮助。如果这是您的问题,则永远不会调用该方法中的内容。

在您的onCreate中:

webView = findViewById(R.id.webView);
webView.setWebViewClient(new customWebView());
webView.setWebChromeClient(new customChromeClient());

自定义类:

private class customChromeClient extends WebChromeClient {
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);

        //check for permissions or show your dialog etc
    }
}

//other methods you may want to override
private class customWebView extends WebViewClient {
    @Override
    public void onPageFinished(WebView view, String url) {

    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView webView, String url) {
        return true;
    }
}

希望这对以后的人有所帮助。

示例以及找到答案的地方: https://gist.github.com/Cheesebaron/ad84740c9bffa7e255c8

答案 2 :(得分:0)

如果位置关闭,并且网站请求位置,则webview致电onGeolocationPermissionsShowPrompt,但仅一次。要使该工作正常进行,意味着每次网站请求位置时,我都会这样做:onGeolocationPermissionsShowPrompt

inner class MyChromeClient: WebChromeClient()
    {

        override fun onGeolocationPermissionsShowPrompt(origin: String?, callback: GeolocationPermissions.Callback?) {
            // Geolocation permissions coming from this app's Manifest will only be valid for devices with API_VERSION < 23.
            // On API 23 and above, we must check for permission, and possibly ask for it.
            //callback?.invoke(origin,true,false)

            val permission=Manifest.permission.ACCESS_FINE_LOCATION

            if (Build.VERSION.SDK_INT<Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(applicationContext,permission)==PackageManager.PERMISSION_GRANTED)
            {
                // we're on SDK < 23 OR user has already granted permission
                callback?.invoke(origin,true,false)
            }
            else{

                if (!ActivityCompat.shouldShowRequestPermissionRationale(this@WebViewActivity,permission))
                {
                    // user clicked on don't asked again
                    alert("Allow location permission to access this feature"){
                        yesButton {
                            val intent=Intent()
                            intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                            intent.data= Uri.fromParts("package",packageName,null)
                            startActivity(intent)
                            callback?.invoke(origin,false,false)
                        }
                        noButton {
                            callback?.invoke(origin,false,false)
                        }
                    }.show()
                }
                else{
                    // permission not granted yet
                    this@WebViewActivity.callback=callback
                    this@WebViewActivity.origin=origin
                    ActivityCompat.requestPermissions(this@WebViewActivity, arrayOf(permission),100)
                }
            }
        }
    }

添加onRequestPermissions结果代码:

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (grantResults.isNotEmpty() && requestCode==100)
        {
            if (grantResults[0]==PackageManager.PERMISSION_GRANTED)
            {
                if (callback!=null)
                    callback?.invoke(origin,true,false)
                return
            }
            else{
                callback?.invoke(origin,false,false)
            }
        }
        callback?.invoke(origin,false,false)
    }

关键是,如果您希望再次调用onGeolocationPermissionsShowPrompt,则需要调用callback?.invoke(origin,false,false),并将这些确切值存储在onGeolocationPermissionsShowPrompt中的参数中