【发布时间】:2019-01-13 22:31:41
【问题描述】:
我正在尝试访问 Android WebView 中可用的 HTML Geolocation API(使用 SDK 版本 24)。
主要问题是 在 JavaScript 中对 navigator.geolocation.getCurrentPosition() 的调用永远不会返回(既没有错误,也没有位置数据),而在应用程序端我检查权限并将它们正确传递给WebView 使用android.webkit.GeolocationPermissions.Callback 类。
更新:在这里澄清一下,“永不返回”是指提供的两个回调 navigator.geolocation.getCurrentPosition(success, error) 都没有被调用过。
在我构建的一个示例应用程序中(只有一个托管 WebView 的小活动)我在清单中声明权限并在应用程序启动时正确请求它们。我看到提示,可以授予或拒绝位置信息的权限。
清单:
<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 控件中打开一个网页。
我在设置中启用了所有必需的选项:
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);
}
}
}
为了对此进行测试,我使用了以下代码(取自 Mozilla API help page,在此处缩短):
function geoFindMe() {
function success(position) {}
function error() {}
navigator.geolocation.getCurrentPosition(success, error);
}
我看到的是在 JavaScript 中对navigator.geolocation.getCurrentPosition(success, error) 的调用永远不会返回。我看到Java中的onGeolocationPermissionsShowPrompt()方法被正确调用,当我在那里检查权限时,我总是得到结果0,即PackageManager.PERMISSION_GRANTED,所以callback.invoke(origin, true, true)在每次调用时都会执行。如果我尝试多次,我会看到对我的 Java 代码的多次调用。尽管如此,在我调用 invoke() 之后,JavaScript 端没有任何反应。
我添加了代码以使用GeolocationPermissions 类中的getOrigins(ValueCallback<Set<String>> callback) 调用来检查授予的权限,如here in the documentation 所述。我在回调中看到允许我的来源请求位置(它们在集合中列出)。
你有什么想法吗?
【问题讨论】:
-
也许 webview.setJavaScriptEnabled (true) 哈哈只是一个猜测。
-
@JRowan 敏锐的眼睛!如果是这样的话我会很高兴,但我只是在从我的项目中复制代码时跳过了那一行。现在修好了。所以,这不是原因。
-
请添加您的复制 git 链接,我想查看您的复制 repo 以提供帮助
标签: javascript android android-webview w3c-geolocation