【问题标题】:Android WebChromeClient WebView onGeolocationPermissionsShowPrompt never firedAndroid WebChromeClient WebView onGeolocationPermissionsShowPrompt 从未触发
【发布时间】:2013-04-05 18:21:57
【问题描述】:

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

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" />

【问题讨论】:

  • onGeolocationPermissionsShowPrompt 仅在应用程序首次运行时显示。使用adb uninstall your_pack_name 删除然后安装它。

标签: android webview gps webchromeclient


【解决方案1】:

onGeolocationShowPrompt 本身并不实际显示提示,它只是在页面请求您的地理位置时调用的一种方法。您需要为用户创建自己的提示,如下所示(放置在 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();

【讨论】:

  • 这是新的吗?我使用了该实现并且之前运行良好(比如一年前?),现在它只是显示它被阻止,没有显示任何提示(截至 2019 年 7 月)。
【解决方案2】:

对于像我一样正在寻找如何修复“从未使用过 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

【讨论】:

    【解决方案3】:

    如果位置被关闭并且如果网站请求位置然后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)
                    }
                }
            }
        }
    

    添加 onRequestPermissionsResult 代码:

    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 中的参数中

    【讨论】:

      猜你喜欢
      • 2018-07-26
      • 2015-10-08
      • 1970-01-01
      • 2019-09-28
      • 2017-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-25
      相关资源
      最近更新 更多