Android webview地理定位数据库打开失败

标签 android sqlite webview geolocation

我有一个使用 javascript geolocation api 的网站,并希望它在 webview 中打开。我在 list 文件中设置了这些权限:

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

在我的 Activity 中,我还设置了 webview 设置:

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

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

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

地理定位本身可以工作,但我无法将地理定位缓存到数据库中。它应该自己进入 CachedGeoposition.db,但是当我启动 webview 时,我得到了这个奇怪的 SQLite 错误:

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 文件是否存在时,它始终存在, 数据库的权限设置为 -rw--------。

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

最佳答案

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

我测试了(没有错误):

  • (模拟器)Galaxy Nexus (2.3.3)(已创建 data/data/package.name/files/CachedGeoposition.db 文件)
  • (模拟器)Galaxy Nexus (3.0)(已创建 data/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 权限(几乎相同):

<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 设置:

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

Web chrome 客户端(相同):

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

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

<!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 中:

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();
}

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

关于Android webview地理定位数据库打开失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11984237/

相关文章:

java - 从 WebView 保存图像

使用 Android 测试框架进行 Android AsyncTask 测试

android - 如何在android中自动创建imageview

android - Android Studio 1.3 中实验性 Gradle 构建工具的 lintOptions

ruby - SQLite 是在 Heroku 上备份 postgres 的好解决方案吗?

android - Android 上是否有比 PhoneGap 更快的 WebView for HTML5 Canvas?

android - 构建xamarin android项目失败,错误XA4212

Android:在我的程序中处理 SQLite 数据库

python - Flask 教程 : Why do we use the app context for the DB connection?

javascript - 你能用 HTML/CSS 和 Javascript 编写 Cocoa 应用程序吗?