从android应用程序访问外部存储中的某个下载的.sqlite数据库

我想在一个基于android的WebView的应用程序中实现一个离线地图function:

使用DownloadManager我从我们的web服务器 (包含地图平铺图像的斑点(“离线地图”)) 下载一个sqlite数据库文件 (类似于.mbtiles的结构 ),并将其存储在android外部存储器中

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

下载似乎工作得很好。 我注册一个BroadcastReceiver来接收DownloadManager.ACTION_DOWNLOAD_COMPLETE并使用SharedPreferences存储path为“map.sqlite”。

要从JavaScript访问数据库以使用WebView的平铺图像, 通过检查URL中的自定义虚构模式名称customhttp:拦截XHRequests

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

我的问题是,我似乎以错误的方式实现openDatabase()因为我得到以下不愉快的错误与相应的行,但无法弄清楚为什么:

 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 

[…]

该文件存在,没有损坏,其path似乎是正确的。 我能够使用SQLite查看应用程序打开文件。

问题:为什么我的代码不工作; 我怎么能使它工作?

我知道这里至less存在三个非常类似的问题,但是这些问题并不那么具体,详细和/或不完全符合我的需要。 阅读本文后,我也没有设法解决这个问题:

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

非常感谢您的帮助!


更新:

我试图在外部存储中使用SQLiteDatabase.openOrCreateDatabase()创build一个新的数据库,以便将其与原始数据库进行比较。 这不是创build – 而是我惊讶地遇到相同的错误信息(无法打开数据库)。

然后我再次尝试使用SQLiteDatabase.openOrCreateDatabase(":memory:", null)打开一个新的数据库,这次在RAM中,并没有抛出任何错误。

因此,我开始认为问题是外部存储的访问限制,或者寻址外部存储而不是数据库文件本身。

Solutions Collecting From Web of "从android应用程序访问外部存储中的某个下载的.sqlite数据库"

我终于设法find了一个相当清醒的错误。

我收到了DownloadManager.ACTION_DOWNLOAD_COMPLETE ,并将URI存储到SharedPreferences的下载数据库中,以便以后在shouldInterceptRequest方法内引用:

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

shouldInterceptRequest我然后调用

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

并由此将URI传递给openDatabase ,而不是单独的Path

我现在Uri.parse(preferences.getString("map_uri", ...)).getPath()和一切正常。 地图加载。

非常感谢您的帮助!