我正在尝试在基于
Android WebView的应用程序中实现离线地图功能:
使用DownloadManager,我从我们的网络服务器下载一个sqlite数据库文件(一个类似.mbtiles的结构),该文件包含地图图块图像(“离线地图”)的blob,并将其存储在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将路径存储到“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
[…]
该文件存在,没有损坏,它的路径似乎是正确的.我可以使用SQLite查看应用程序打开该文件.
问题:为什么我的代码不工作?我该怎么办?
我知道在这里存在至少三个与上述错误信息非常相似的问题,但它们并不具体,详细和/或不完全符合我的需要.阅读本文后我也没有解决问题:
非常感谢您的帮助!
更新:
我尝试在外部存储中使用SQLiteDatabase.openOrCreateDatabase()创建一个新数据库,以便将其与原始数据库进行比较.它没有创建 – 相反,我惊讶地遇到了相同的错误消息(无法打开数据库).
然后我再次试图打开一个新的数据库,这次在RAM中,使用SQLiteDatabase.openOrCreateDatabase(“:memory:”,null),并且没有任何错误.
因此,我开始认为这个问题是对外部存储的一些访问限制,或者在寻址外部存储而不是数据库文件本身时出错.