android sqlite android-sqlite

Acceso a una determinada base de datos.sqlite descargada en almacenamiento externo desde una aplicaciĆ³n de Android



android-sqlite (1)

Estoy tratando de implementar una función de mapa sin conexión en una aplicación basada en WebView de Android:

Utilizando DownloadManager , descargo un archivo de base de datos sqlite (de una estructura como .mbtiles) de nuestro servidor web , que contiene manchas de las imágenes de mosaico del mapa (el "mapa fuera de línea") y lo almaceno en el almacenamiento externo de Android a través de

public void downloadMap() { downloadManager = (DownloadManager) getActivity().getSystemService(Activity.DOWNLOAD_SERVICE); DownloadManager.Request r = new DownloadManager.Request(Uri.parse("http://sry.youtoknow.idontwant/map.sqlite")); r.setDestinationInExternalFilesDir(getContext(), "map", "map.sqlite"); downloadManager.enqueue(r); }

La descarga parece funcionar perfectamente bien. Registro un BroadcastReceiver para recibir DownloadManager.ACTION_DOWNLOAD_COMPLETE y almaceno la ruta a "map.sqlite" usando SharedPreferences .

Para acceder a la base de datos desde JavaScript para usar las imágenes de mosaico en la vista WebView , intercepto las peticiones XH al buscar un nombre de esquema ficticio personalizado customhttp: en la URL:

webView.setWebViewClient(new WebViewClient() { public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { String url = request.getUrl().toString(); if (!url.startsWith("customhttp:")) { return null; } else { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext()); SQLiteDatabase db = SQLiteDatabase.openDatabase(preferences.getString("map_uri", Environment.getExternalStorageDirectory().getPath() + "berlin.sqlite"), null, SQLiteDatabase.OPEN_READONLY); } } });

Mi problema es que parece que implemento openDatabase() de manera incorrecta, ya que obtengo el siguiente error desagradable con la línea correspondiente, pero no puedo entender por qué:

E/SQLiteLog(#####): (14) cannot open file at line ##### of [##########] E/SQLiteLog(#####): (14) os_unix.c:#####: (2) open(//file:///storage/emulated/0/Android/data/idontwant.youtoknow.sry/files/map/map.sqlite) - E/SQLiteDatabase(#####): Failed to open database ''file:///storage/emulated/0/Android/data/idontwant.youtoknow.sry/files/map/map.sqlite''. E/SQLiteDatabase(#####): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

[...]

El archivo existe, no está dañado y su ruta parece ser correcta. Pude abrir el archivo utilizando una aplicación de visualización SQLite.

Pregunta: ¿Por qué mi código no funciona? ¿Cómo puedo hacer que funcione?

Soy consciente de que existen al menos tres preguntas muy similares con el mensaje de error anterior aquí, pero no son tan específicas, detalladas y / o no se ajustan exactamente a mis necesidades. Tampoco logré resolver el problema después de leer este artículo:

http://blog.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ .

¡Muchas gracias por su ayuda!

ACTUALIZAR:

Intenté crear una nueva base de datos utilizando SQLiteDatabase.openOrCreateDatabase() en un almacenamiento externo para poder compararla con la base de datos original. No se creó, en cambio me enfrenté sorprendentemente al mismo mensaje de error (no se pudo abrir la base de datos).

Luego volví a intentar abrir una nueva base de datos, esta vez en la RAM, utilizando SQLiteDatabase.openOrCreateDatabase(":memory:", null) y no se produjo ningún error.

Por lo tanto, empiezo a pensar que el problema es una restricción de acceso al almacenamiento externo o un error al abordar el almacenamiento externo en lugar del propio archivo de base de datos.


Finalmente me las arreglé para encontrar el error, bastante aleccionador.

Recibí DownloadManager.ACTION_DOWNLOAD_COMPLETE y SharedPreferences el URI en la base de datos descargada en SharedPreferences para referencias posteriores dentro del método shouldInterceptRequest usando:

... Cursor c = downloadManager.query(query); if (c.moveToFirst()) { if (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) { Editor editor = PreferenceManager.getDefaultSharedPreferences(getContext()).edit(); editor.putString("map_uri", c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))); editor.commit(); } } c.close();

En shouldInterceptRequest entonces llamé

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext()); SQLiteDatabase db = SQLiteDatabase.openDatabase(preferences.getString("map_uri", Environment.getExternalStorageDirectory().getPath() + "map.sqlite"), null, SQLiteDatabase.OPEN_READONLY);

y de este modo pasó el URI a openDatabase , no solo la ruta .

Ahora Uri.parse(preferences.getString("map_uri", ...)).getPath() y todo funciona. El mapa se carga.

¡Muchas gracias por su ayuda!