gpt4 book ai didi

android - 如何使用 Uri 对象打开现有的 SQLite 数据库?

转载 作者:行者123 更新时间:2023-11-30 05:09:08 52 4
gpt4 key购买 nike

我正在使用 Intent.ACTION_GET_CONTENT 选择一个文件。

onActivityResult 方法中,我得到了 Uri:

Uri selectedfile = data.getData();

如何使用 Uri 对象 selectedfile 打开 SQLite 数据库?这不起作用:

SQLiteDatabase database = SQLiteDatabase.openDatabase(selectedfile.getPath(), null, SQLiteDatabase.OPEN_READONLY);

最佳答案

您不应该尝试从 Uri 打开 SQLiteDatabase。

SQLiteDatabase 被设计为直接与文件系统一起工作:它需要锁定和解锁数据库文件并管理单独的预写日志记录(-shm 和-wal)文件,而 Uri 不一定引用 file://中的任何内容模式。相反,它可以是任何内容,从 https://或 content://到自定义应用程序定义的模式。

特别是自 Android 7.0 以来,Google 强制使用 content://uri 在应用程序之间共享文件(这正是您的情况)。取自此处:https://developer.android.com/about/versions/nougat/android-7.0-changes.html :

For apps targeting Android 7.0, the Android framework enforces the StrictMode API policy that prohibits exposing file:// URIs outside your app. If an intent containing a file URI leaves your app, the app fails with a FileUriExposedException exception.

To share files between applications, you should send a content:// URI and grant a temporary access permission on the URI. The easiest way to grant this permission is by using the FileProvider class. For more information on permissions and sharing files, see Sharing Files.

相反,您应该获取 ContentResolver,从中打开 uri InputStream 并将流内容保存到本地临时文件,然后在其上使用 SQLiteDatabase.openDatabase(filePath):

void openDatabaseFromFileDialog() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT).setType("*/*");
startActivityForResult(Intent.createChooser(intent, "Select a database"), DB_FILE_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == DB_FILE_REQUEST && resultCode == RESULT_OK) {
Uri dataUri= data.getData();
openDatabaseFromUri(dataUri);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}

void openDatabaseFromUri(Uri uri) {
InputStream inputStream = application.getContentResolver().openInputStream(uri);

File file = File.createTempFile("sqlite", "");

FileOutputStream outputStream = new FileOutputStream(file);
byte[] buff = new byte[1024];
int read;
while ((read = inputStream.read(buff, 0, buff.length)) > 0)
outputStream.write(buff, 0, read);
inputStream.close();
outputStream.close();

openDatabaseFromFile(file.getPath());
}

void openDatabaseFromFile(String filePath) {
// your code here
}

此外,当您从另一个应用程序(可能是第三方)获取 SQLite 流时,我强烈建议您在单独的线程/AsyncTask/等中使用数据库。您永远不知道您收到了多少 PB: )

关于android - 如何使用 Uri 对象打开现有的 SQLite 数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54008073/

52 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com