Подтвердить что ты не робот

Не удалось открыть базу данных геоданных в веб-браузере Android

У меня есть сайт, использующий javascript geolocation api и хочу, чтобы он открывался в веб-просмотре. Я установил эти разрешения в файле манифеста:

<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.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, но когда я запускаю веб-просмотр, я получаю эту странную ошибку 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 в Проводнике, он всегда присутствует, и разрешения для db установлены на -rw -------.

Я что-то пропустил в настройках, что может заставить базу данных не открыться правильно? Я новичок в Android и пытаюсь найти решение в течение 2 дней. Любая помощь будет принята с благодарностью. Спасибо.

4b9b3361

Ответ 1

Я опубликую решение, которое сработало для меня в надежде, что оно может дать некоторые идеи о том, где может быть ошибка. Это также поможет, если вы сможете предоставить подробную информацию об устройстве (эмуляторе)/os, на котором вы тестируете.

Я тестировал (без ошибок):

  • (эмулятор) Galaxy Nexus (2.3.3) (файл данных/данных/package.name/files/CachedGeoposition.db создан)
  • (эмулятор) Galaxy Nexus (3.0) (данные/данные/package.name/files/CachedGeoposition.db файл создан)
  • HTC One S (4.1.1) (созданный файл данных/данных/package.name/files/CachedGeoposition.db)
  • Galaxy S3 (4.3) (не мог видеть файл, так как мой телефон не внедрен, и есть некоторые ошибки "run-as" в 4.3)
  • Nexus 7 (4.4.4) - веб-просмотр выше KIT KAT немного изменился, и файл больше не существует, но не было обнаружено ошибок (даже при указании неправильного пути к папкам баз данных)
  • (эмулятор) 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"/>

Настройки веб-представления:

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

Клиент веб-хрома (тот же):

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>

Кроме того, для локального теста вы можете создать файл, содержащий html в разделе "/assets/www/index.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();
}

Я не смог воспроизвести вашу ошибку, не указав неправильный жесткий путь к папке "базы данных".

Ответ 2

Линия

D/WebKit (22653): база данных SQLite не загружена из /CachedGeoposition.db

интересен

Попробуйте также установить соответствующий путь DB в WebSettings.setDatabasePath, возможно, это используется как корень для пути geo db

Ответ 3

Я знаю, что это старый вопрос, но любой, кто с этим вопросом, может найти интересную фокусировку на этой функции:

mWebView.getSettings().setGeolocationDatabasePath(getFilesDir().getPath());

Геолокация использует базы данных для сохранения кэшированных позиций и разрешений между сеансами. Этот вызов устанавливает местоположение базы данных.

Вместо того, чтобы устанавливать фиксированный путь как параметр, вы должны получить динамический вызов:

getFilesDir().getPath()