为了账号安全,请及时绑定邮箱和手机立即绑定

具有完全限定的数据库路径名的SQLiteOpenHelper问题

具有完全限定的数据库路径名的SQLiteOpenHelper问题

梵蒂冈之花 2019-10-18 10:26:28
在我的应用中,我使用...myFilesDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()                      + "/Android/data/" + packageName + "/files");myFilesDir.mkdirs();很好,最终的路径是.../mnt/sdcard/Android/data/com.mycompany.myApp/files我需要一个要存储在SD卡上的SQLite数据库,因此我按如下方式扩展了SQLiteOpenHelper ...public class myDbHelper extends SQLiteOpenHelper {    public myDbHelper(Context context, String name, CursorFactory factory, int version) {        // NOTE I prefix the full path of my files directory to 'name'        super(context, myFilesDir + "/" + name, factory, version);    }    @Override    public void onCreate(SQLiteDatabase db) {        // Create tables and populate with default data...    }}到目前为止一切顺利-我第一次打电话getReadableDatabase()或getWriteableDatabase()在SD卡上创建了一个空DB并将其onCreate()填充。所以这就是问题所在-该应用程序可能需要5到6个人进行Beta测试,并且像我一样,他们正在运行Android v2.2,并且一切正常。我有一个测试器,但是正在运行v2.1,并且myDbHelper在首次使用时尝试创建数据库时,它因以下原因而崩溃...E/AndroidRuntime( 3941): Caused by: java.lang.IllegalArgumentException: File /nand/Android/data/com.mycompany.myApp/files/myApp-DB.db3 contains a path separatorE/AndroidRuntime( 3941): at android.app.ApplicationContext.makeFilename(ApplicationContext.java:1445)E/AndroidRuntime( 3941): at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:473)E/AndroidRuntime( 3941): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)E/AndroidRuntime( 3941): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)E/AndroidRuntime( 3941): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)文件目录的路径是一个奇数(“ / nand”),因为它是内部存储器,尽管不是手机自己的内部存储器-但这是getExternalStorageDirectory()此设备返回的路径。我可以看到三个可能的答案...尽管在v2.2上可以接受,但是不建议为数据库名称指定完全限定的路径,并且在早期版本中会失败SD卡存储可接受完全限定的路径,但是“ / nand”路径被解释为“内部”路径,在这种情况下,仅相对路径可接受我完全想不到的其他东西如果上述任何一项或全部适用,那么如果有人可以帮助我解决这个问题,我将不胜感激。谢谢。
查看完整描述

3 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

从历史上看,您无法通过使用路径SQLiteOpenHelper。它仅适用于简单的文件名。我没有意识到他们放宽了Android 2.2中的限制。


如果您希望使用SD卡上的数据库,并且希望支持Android 2.1及更低版本,则不能使用SQLiteOpenHelper。



查看完整回答
反对 回复 2019-10-18
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

k3b的答案很棒。它使我工作。但是,在使用API级别11或更高版本的设备上,您可能会看到它停止工作。这是因为添加了新版本的openOrCreateDatabase()方法。现在,它包含以下签名:


openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags, DatabaseErrorHandler errorHandler)

在某些具有此方法的设备上,这似乎是默认调用的方法。


为了使此方法在这些设备上起作用,您需要进行以下更改:


首先,编辑您现有的方法,使其仅将调用结果返回给新方法。


@Override

public SQLiteDatabase openOrCreateDatabase(String name, int mode,

        CursorFactory factory) {

    return openOrCreateDatabase(name, mode, factory, null);


}

其次,使用以下代码添加新的替代。


@Override

public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) {

    SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(),null,errorHandler);


    return result;

}

该代码与k3b的代码非常相似,但是请注意,SQLiteDatabase.openOrCreateDatabase采用String而不是File,并且我使用了允许DatabaseErrorHandler对象的版本。


查看完整回答
反对 回复 2019-10-18
  • 3 回答
  • 0 关注
  • 676 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信