提问者:小点点

如何使用即将到来的作用域存储,通过外部存储中的空间写入SQLite文件?


我们的应用程序要求之一是,一些SQLite文件应该保留和备份,即使应用程序被卸载。

我们通过将SQLite文件通过Room写入位置< code > environment . getexternalstreatedirectory 来实现这一点

@Database(
    entities = {Backup.class},
    version = 1
)
public abstract class LocalBackupNamedRoomDatabase extends RoomDatabase {
    public abstract BackupDao backupDao();

    public static LocalBackupNamedRoomDatabase newInstance(String dbName) {
        LocalBackupNamedRoomDatabase INSTANCE = Room.databaseBuilder(
                WeNoteApplication.instance(),
                LocalBackupNamedRoomDatabase.class,
                dbName
        )
                .build();

        return INSTANCE;
    }
}
public static String getBackupDirectory() {
    if (backupDirectory == null) {
        File _externalStorageDirectory = Environment.getExternalStorageDirectory();
        if (_externalStorageDirectory == null) {
            return null;
        }

        try {
            backupDirectory = _externalStorageDirectory.getCanonicalPath();
        } catch (IOException e) {
            Log.e(TAG, "", e);
        }

        if (backupDirectory == null) {
            return null;
        }

        backupDirectory = toEndWithFileSeperator(backupDirectory) + "com.yocto.wenote" + File.separator + "backup" + File.separator;
    }

    return backupDirectory;
}
LocalBackupNamedRoomDatabase.newInstance(
    getBackupDirectory() + "local-backup"
).backupDao().insert(backup)

根据这个,我的理解是Environment.getExextalStorageDirectory可能不再可用了(我是正确的吗??)。

我的猜测是,为了实现相同的行为,我可能需要使用< code>MediaStore。下载?但是怎么做呢?

有人能为上述用例提供一个具体的例子吗?或者,在作用域存储下,我们不再可能实现这种行为?


共2个答案

匿名用户

根据我自己对Q beta 2模拟器的实验,使用带有目标SdkVersion'Q'的测试应用程序:

最初 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).exists() 是假的,这让我相信你甚至无法在 Q 中访问它。然后我发现 mkdirs() 可以工作,然后我可以读取和写入此文件夹的沙盒视图,仅限于我的应用程序文件。这有一个有趣的副作用,即多个应用程序可以将同名文件写入“下载”文件夹,这就是它们在模拟器的默认文件应用程序中的显示方式!

正如文档所提到的,卸载然后重新安装后,您将无法访问自己的文件。因此,为了在卸载后从下载中恢复 sqlite 文件,您必须:

    < li >“允许用户使用系统的文件选择器应用程序选择文件。”(来自文档) < li >这将给你一个URI而不是一个文件。因为< code>SQLiteDatabase只能读取< code >文件,所以您需要将URI作为一个流打开,并将其写入您控制的某个真实文件,例如缓存或内部存储。

这是一种痛苦,但对于大多数用例来说是可行的。对于非常大的数据库文件(例如可能为数百 MB 或更多的 mapbox 图块)存储在实际的 SD 卡上会变得棘手,因为它们不适合常规的“外部”存储。

匿名用户

如上所述,卸载应用程序后,位于外部存储中的文件将被删除。因此,您可以考虑使用getExextalStoragePublicDirectory函数将文件存储在顶级共享存储中。如果要存储在DOWNLOADS目录中,可以使用以下命令获取目录路径。

File path = Environment.getExternalStoragePublicDirectory(
        Environment. DIRECTORY_DOWNLOADS);

希望有帮助。