Android WebChromeClient WebView onGeolocationPermissionsShowPrompt никогда не срабатывает
У меня есть веб-страница с вызовом 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" />
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();
Хорошо, если местоположение отключено и если сайт запрашивает местоположение, то 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
Это должно помочь всем, кто ищет, как исправить сообщение "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