Android webview 地理定位数据库无法打开

时间:2023-03-21
本文介绍了Android webview 地理定位数据库无法打开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个使用 javascript geolocation api 的网站,并希望它在 web 视图中打开.我在清单文件中设置了这些权限:

I have website using javascript geolocation api and want it to open in a webview. I set up these permissions in the manifest file:

<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_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

在我的活动中,我还设置了 webview 设置:

In my activity, I also set webview settings:

webview.getSettings().setDatabaseEnabled(true);
webview.getSettings().setDomStorageEnabled(true);
webview.getSettings().setGeolocationDatabasePath("/data/data/com.my.app/databases");
webview.getSettings().setGeolocationEnabled(true);

我还处理了 javascript 地理定位对话框:

And I also handled javascript geolocation dialog:

webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);
    }
});

地理位置本身正在工作,但我无法将地理位置缓存到数据库中.它应该在 CachedGeoposition.db 中自行完成,但是当我启动 webview 时,我得到了这个奇怪的 SQLite 错误:

Geolocation itself is working, but I am not able to cache geoposition into the database. It should be doing it by itself into CachedGeoposition.db, but when I start the webview, i get this strange SQLite error:

E/SQLiteLog(22653): (14) cannot open file at line 30174 of [00bb9c9ce4]
E/SQLiteLog(22653): (14) os_unix.c:30174: (2) open(/CachedGeoposition.db) -
D/WebKit  (22653): ERROR:
D/WebKit  (22653): SQLite database failed to load from /CachedGeoposition.db
D/WebKit  (22653): Cause - unable to open database file
D/WebKit  (22653):
D/WebKit  (22653): external/webkit/Source/WebCore/platform/sql/SQLiteDatabase.cp
p(71) : bool WebCore::SQLiteDatabase::open(const WTF::String&, bool)

当我在文件资源管理器中检查 CachedGeoposition.db 文件是否存在时,它总是在那里,db的权限设置为-rw------.

When I check existence of CachedGeoposition.db file in File Explorer, it is always there, and permissions of the db are set to -rw-------.

我是否在设置中遗漏了一些可能导致数据库无法正确打开的内容?我是 Android 新手,现在正在尝试寻找 2 天的解决方案.任何帮助将不胜感激.谢谢.

Did I miss something in settings what could cause database not to open correctly? I'm new to Android and trying to find solution for 2 days now. Any help would be greatly appreciated. Thank you.

推荐答案

我将发布一个对我有用的解决方案,希望它可以提供一些关于错误可能在哪里的想法.如果您可以提供有关您正在测试的设备(模拟器)/操作系统的详细信息,这也会有所帮助.

I'll post a solution that worked for me in the hope that it might provide some ideas on where the error might be. It would also help if you could provide details about the device(emulator)/os on which you're testing.

我测试过(没有错误):

I tested on (with no errors):

  • (模拟器)Galaxy Nexus (2.3.3)(创建数据/数据/package.name/files/CachedGeoposition.db 文件)
  • (模拟器)Galaxy Nexus (3.0)(创建数据/data/package.name/files/CachedGeoposition.db 文件)
  • HTC One S (4.1.1)(data/data/package.name/files/CachedGeoposition.db 文件已创建)
  • Galaxy S3 (4.3)(看不到文件,因为我的手机没有 root 并且在 4.3 上有一些运行方式"错误)
  • Nexus 7 (4.4.4) - KIT KAT 上方的 webview 发生了一些变化,并且文件不再存在,但没有显示错误(即使提供了错误的数据库"文件夹路径)
  • (模拟器)Galaxy S4 (5.0)(与 4.4.4 相同)

AndroidManifest 权限(差不多):

AndroidManifest permissions (pretty much the same):

<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_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

网页视图设置:

WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setGeolocationDatabasePath(getFilesDir().getPath());
webSettings.setGeolocationEnabled(true);

Web chrome 客户端(同):

Web chrome client (the same):

webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);
    }
});

获取地理位置的测试 html 文件:

Test html file for getting the geolocation:

<!DOCTYPE html>
<html>
<head>
<script>
var x = document.getElementById("demo");

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition, showError);
    } else {
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}

function showPosition(position) {
    var latlon = position.coords.latitude + "," + position.coords.longitude;
    document.getElementById("locationHolder").innerHTML = latlon;
}

function showError(error) {
    switch(error.code) {
        case error.PERMISSION_DENIED:
            x.innerHTML = "User denied the request for Geolocation.";
            break;
        case error.POSITION_UNAVAILABLE:
            x.innerHTML = "Location information is unavailable";
            break;
        case error.TIMEOUT:
            x.innerHTML = "The request to get user location timed out.";
            break;
        case error.UNKNOWN_ERROR:
            x.innerHTML = "An unknown error occurred.";
            break;
    }
}
</script>
</head>

<body>

<p id="demo">Click the button to get your position.</p>

<div id="locationHolder">No location</div>
<button onclick="getLocation()">Get position</button>

</body>
</html>

此外,对于本地测试,您可以在/assets/www/index.html"下创建一个包含 html 的文件,并使用以下代码将其加载到 webview 中:

Also, for a local test, you could created a file containing the html under '/assets/www/index.html' and use the following code to load it into the webview:

try {
    String html = readAssetFile("www/index.html");
    webview.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);
} catch (IOException e) {
}

读取资产文件方法:

private String readAssetFile(String filePath) throws IOException {
    StringBuilder buffer = new StringBuilder();
    InputStream fileInputStream = getAssets().open(filePath);
    BufferedReader bufferReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
    String str;

    while ((str=bufferReader.readLine()) != null) {
        buffer.append(str);
    }
    fileInputStream.close();

    return buffer.toString();
}

如果不提供数据库"文件夹的错误硬编码路径,我无法重现您的错误.

I couldn't reproduce your error without providing a wrong hardcoded path to the 'databases' folder.

这篇关于Android webview 地理定位数据库无法打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:navigator.geolocation.getCurrentPosition 在 Android 浏览器上失败 下一篇:将一个 LatLng 向另一个 LatLng 移动 5 米

相关文章