Вы не должны пытаться открыть базу данных SQLite из Uri.
SQLiteDatabase предназначен для работы непосредственно с файловой системой: он должен блокировать и разблокировать файл базы данных и управлять отдельными файлами журналирования с опережением записи (-shm и -wal), в то время как Uri не обязательно ссылается на какой-либо контент в файле: // схемы. Вместо этого это может быть что угодно, от https: // или content: // до пользовательских схем, определенных приложением.
Тем более, что Android 7.0 Google навязывает использование контента: // uris для обмена файлами между приложениями (это как раз ваш случай). Взяты отсюда: https://developer.android.com/about/versions/nougat/android-7.0-changes.html:
Для приложений, ориентированных на Android 7.0, платформа Android применяет политику API StrictMode, которая запрещает показ URI file: // вне вашего приложения. Если намерение, содержащее файловый URI, покидает ваше приложение, приложение завершается ошибкой с исключением FileUriExposedException.
Чтобы обмениваться файлами между приложениями, вы должны отправить URI содержимого: // и предоставить временное разрешение на доступ к URI. Самый простой способ предоставить это разрешение - использовать класс FileProvider. Для получения дополнительной информации о разрешениях и совместном использовании файлов см. Общий доступ к файлам.
Вместо этого вы должны получить 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 / и т. Д. Вы никогда не знаете, сколько петабайт вы получаете: )