На самом деле я работаю над приложением, в котором пользователь может выбрать любой файл, который загружается на сервер.Этот пользователь должен ввести имя для этого файла, и когда файл загружен, файл отображается в списке с введенным именем и типом файла (.exe, .svg, любой тип файла).
Проблема, с которой я столкнулся, заключается в том, что я не могу извлечь расширение файла из файлов, выбранных на смартфоне с Android 9. Проблема не возникает на устройствах с Android 8 и менее или на планшетах с Android 9Я тестирую приложение только с Android Studios Emulator.
Выбор файла начинается со следующего намерения:
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent target = Intent.createChooser(intent, "Select Picture");
startActivityForResult(target, PICKFILE_REQUEST_CODE);
Когда пользователь выбрал любой тип файла, вызывается onActivityResult.В этом методе я вызываю getPath из класса FileUtils, чтобы извлечь расширение файла.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = new Uri.Builder().build();
if (resultCode == RESULT_OK) {
switch (requestCode) {
case PICKFILE_REQUEST_CODE: {
String path = new File(data.getData().getPath()).getAbsolutePath();
if (path != null) {
uri = data.getData();
Context context = this.getApplicationContext();
path = FileUtils.getPath(context.getContentResolver(),uri);
name = path.substring(path.lastIndexOf("."));
extension = path.substring(path.lastIndexOf(".") + 1);
}
break;
}
}
}
Метод getPath из класса FileUtils ( класс из этого репозитория ) оценивает файлчерез URI, какой это тип документа, но ответственным за этот случай является следующая часть:
public static String getPath(final ContentResolver contentResolver, final Uri uri) {
//some irrelevant code ..
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
// depending on the device, the downloads folder can have different names
final String id = DocumentsContract.getDocumentId(uri);
final List<Uri> uris = new ArrayList<>();
uris.add(ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)));
uris.add(ContentUris.withAppendedId(Uri.parse("content://downloads/my_downloads"), Long.valueOf(id)));
uris.add(ContentUris.withAppendedId(Uri.parse("content://downloads/all_downloads"), Long.valueOf(id)));
String res;
for(int i = 0; i < uris.size(); i++) {
try {
res = getDataColumn(contentResolver, uris.get(i), null, null);
if(res != null)
return res;
} catch (Exception e) {}
}
}
Метод getDataColumn запрашивает столбец файла, в котором сохранен физический путь файла:
public static String getDataColumn(ContentResolver contentResolver, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
String col = "";
try {
cursor = contentResolver.query(uri, projection, selection, selectionArgs,null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
col = cursor.getString(column_index);
}
}finally {
if (cursor != null)
cursor.close();
}
return col;
}
Когда я тестирую приложение с любым эмулятором смартфона (кроме тех, что на Android 9), путь, который я получаю, выглядит, например, следующим образом: E / AddItemActivity: результат, путь: / storage / emulated / 0 / Download / SampleVideo_176x144_1mb.3gp Но когда дело доходит до эмулятора смартфона с Android 9, путь всегда пуст.
Заранее спасибо!