【问题标题】:Not able to open database in read/write mode无法以读/写模式打开数据库
【发布时间】:2020-06-23 01:31:37
【问题描述】:

我遇到以下错误:

不是错误(代码 0):无法以读/写模式打开数据库。

我已经添加了

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我正在尝试在 SD 卡中存在的数据库中输入数据,我能够通过“OPEN_READONLY”读取数据库中已经存在的数据。使用“OPEN_READWRITE”时出现错误

【问题讨论】:

  • 哪个安卓版本? SD卡上的数据库在哪里?你用什么代码打开数据库? SD卡是读写挂载的吗?
  • 我们如何检查 SD 卡是否以读写方式挂载?
  • /proc/mounts 中的 SD 卡条目有 rw 标志
  • 在我看来您使用的是getReadableDatabase() 而不是getWritableDatabase()
  • 我遇到了同样的错误。您找到解决方案了吗?我的数据库在 SD 卡中。

标签: android android-sqlite


【解决方案1】:

你的问题不是很清楚,但我会尽力回答。

很可能是您的数据库:

  1. 还不存在,你必须创建它;
  2. 您的database file is read only,您必须更改它(This question 可能相关)。

对于#2,不要使用SQLiteOpenHelper#getReadableDatabase(),而是使用SQLiteOpenHelper#getWritableDatabase


如果您的数据库位于外部存储单元上,您还有其他一些事情需要检查:

  1. 当前是否安装了外部存储?如果没有,则无法访问数据库。
  2. 是否以只读方式安装?如果是这样,您将不得不更改此设置。
  3. 您检查过路径吗?对吗?

问题可能出在这些主题中。

要检查它是否以只读方式安装,请尝试以下操作:

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

取自here

有关Environment课程的更多信息,请refer to the docs

【讨论】:

  • 当我的数据库存在于手机的内部存储器中时,我能够读/写。
  • 那么,您是在尝试使用 SD 卡上的数据库吗?
  • 是的,我正在尝试使用 SD 卡上存在的数据库
  • 我可以在 OPEN_READONLY 中使用 SD 卡上的数据库。你能告诉我如何检查它是只读还是读/写?
  • 编辑了答案。
【解决方案2】:

4.4 KitKat版本中引入了一些与 Android 如何处理存储和数据安全相关的更改。

例如,即使isExternalStorageReadable() 将返回 true,您将无法写入外部 SD 卡,而只能写入 Environment.getExternalStorageDirectory() 返回的目录。

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

为了能够删除、写入、移动文件,您必须使用存储访问框架,它可以让您访问手机上的文件以及任何远程文件,例如 Google 云端硬盘中的文件。

要打开数据库,您必须提供路径,但 Document Provider Api 仅允许您打开输入流或移动文件,因此为了打开数据库,您必须将文件移动/复制到某些 Private内部存储Environment.getExternalStorageDirectory() 目录。

有关此主题的更多信息:

https://developer.android.com/guide/topics/providers/document-provider.html

https://stackoverflow.com/a/43317703/1502079

https://stackoverflow.com/a/21674485/1502079

【讨论】:

    【解决方案3】:

    在 Android API 4.3 及更低版本中,您可以在外部 SD 卡中打开数据库,此代码可用于读写:

    SQLiteDatabase.openDatabase(DB_PATH, null,SQLiteDatabase.NO_LOCALIZED_COLLATORS);
    

    从 API 4.4 开始,您只能在外部 SD 卡 READ_ONLY 中打开数据库,您必须使用此代码:

    SQLiteDatabase.openDatabase(DB_PATH, null,SQLiteDatabase.OPEN_READONLY);
    

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-25
      • 1970-01-01
      相关资源
      最近更新 更多