В моем приложении для Android мне нужно загрузить текстовый файл из хранилища, используя диалог выбора файлов. Некоторое время назад я следовал инструкциям в этой теме выбора файлов Android (оригинальный ответ).
На телефоне с Android 4.2.2 (API 17) все отлично работает. Этот код (фактически как uri.getPath()
) возвращает реальный путь к файлу:
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
...
}
...
}
...
}
Возвращает что-то вроде этого: /storage/sdcard1/Directory/myFile.txt
.. и я могу продолжить работу с файлом.
Однако на телефонах с Android 7 и 8 (API 24-26) cursor.getString(column_index)
всегда возвращает null
, а uri.getPath()
пути возврата, такие как:
/document/254
- Android 8 (внешнее хранилище)
/document/primary:myFile.txt
- Android 8 (внутренняя память)
/document/C5F9-13FC:myFile.txt
- Android 7
... и когда я хочу работать с файлом, созданным new File(path)
, и читать его содержимое с помощью BufferedReader, я получаю FileNotFoundException
.
Я не думаю, что это проблема с правами доступа, потому что когда я читаю файл с жестко заданным путем, используя следующий код, все работает нормально:
File storage = Environment.getExternalStorageDirectory();
File file = new File(storage, fileName);
Мой вопрос:
Есть ли какой-нибудь способ получить реальный путь к файлу от средства выбора файлов или я должен решить эту проблему на устройствах с более новым Android API, совершенно иначе, как при использовании внешней библиотеки?