Я пытаюсь получить доступ к API геолокации HTML, доступному в Android WebView (с использованием SDK версии 24).
Основная проблема заключается в том, что вызов navigator.geolocation.getCurrentPosition()
в JavaScript никогда не возвращается (ни с ошибкой, ни с данными позиции), а на стороне приложения я проверяю разрешения и правильно передаю их в WebView с помощью android.webkit.GeolocationPermissions.Callback
Класс android.webkit.GeolocationPermissions.Callback
.
ОБНОВЛЕНИЕ: просто чтобы пояснить здесь, "никогда не возвращается", я имею в виду, что ни один из слишком поданных обратных вызовов navigator.geolocation.getCurrentPosition(success, error)
когда-либо вызываются.
В примере приложения, которое я построил, чтобы протестировать это (только с одним небольшим хостингом WebView), я объявляю разрешения в манифесте и запрашиваю их правильно в начале приложения. Я вижу приглашение и могу предоставить или запретить разрешение на информацию о местоположении.
Manifest:
<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" />
Код в основной форме:
public boolean checkFineLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION) && !mIsPermissionDialogShown) {
showPermissionDialog(R.string.dialog_permission_location);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ACCESS_FINE_LOCATION);
}
return false;
} else {
return true;
}
}
Я могу проверить разрешения во время выполнения с помощью Context.checkSelfPermission()
и я вижу, что соответствующие разрешения предоставляются моему приложению.
Затем я пытаюсь открыть веб-страницу в WebView
управления WebView
. Я включаю все необходимые параметры в настройках:
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setAppCacheEnabled(true);
mWebSettings.setDatabaseEnabled(true);
mWebSettings.setDomStorageEnabled(true);
mWebSettings.setGeolocationEnabled(true);
mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
mWebSettings.setSupportZoom(true);
Я использую следующую перегрузку WebChromeClient
для обработки запросов геолокации от JavaScript:
protected class EmbeddedChromeClient extends android.webkit.WebChromeClient {
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
android.webkit.GeolocationPermissions.Callback callback) {
// do we need to request permissions ?
if (ContextCompat.checkSelfPermission(EmbeddedBrowserActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// this should never happen, it means user revoked permissions
// need to warn and quit?
callback.invoke(origin, false, false);
}
else {
callback.invoke(origin, true, true);
}
}
}
Чтобы проверить это, я использую следующий код (взятый из справочной страницы API Mozilla, сокращенный здесь):
function geoFindMe() {
function success(position) {}
function error() {}
navigator.geolocation.getCurrentPosition(success, error);
}
Я вижу, что вызов navigator.geolocation.getCurrentPosition(success, error)
в JavaScript никогда не возвращается. Я вижу, что onGeolocationPermissionsShowPrompt()
в Java правильно называется, и когда я проверяю разрешения, я всегда получаю результат 0, то есть PackageManager.PERMISSION_GRANTED
, поэтому callback.invoke(origin, true, true)
выполняется при каждом вызове. Если я попробую несколько раз, я вижу несколько вызовов моего Java-кода. Тем не менее, ничего не происходит на стороне JavaScript здесь после вызова invoke()
.
Я добавил код для проверки разрешенных прав с помощью вызова getOrigins(ValueCallback<Set<String>> callback)
в классе GeolocationPermissions
, как описано здесь в документации. Я вижу в обратном вызове, что в моем происхождении разрешено запрашивать местоположения (они перечислены в наборе).
Какие-нибудь идеи, что может быть неправильно здесь?