Ответ 1
Просто используйте getContentResolver().openInputStream(uri)
, чтобы получить InputStream
из URI.
В моем приложении пользователь должен выбрать аудиофайл, который затем обрабатывает приложение. Проблема в том, что для того, чтобы приложение выполняло то, что я хочу делать с аудиофайлами, мне нужно, чтобы URI был в формате файла. Когда я использую собственный музыкальный плеер Android для просмотра аудиофайла в приложении, URI является URI контента, который выглядит следующим образом:
content://media/external/audio/media/710
Однако, используя приложение популярного файлового менеджера Astro, я получаю следующее:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
Последнее гораздо более доступно для меня, но я, конечно, хочу, чтобы приложение имело функциональность с аудио файлом, который пользователь выбирает, независимо от программы, которую они используют для просмотра своей коллекции. Итак, мой вопрос в том, есть ли способ конвертировать URI стиля content://
в URI file://
? В противном случае, что бы вы порекомендовали мне решить эту проблему? Вот код, вызывающий выборщика, для справки:
Intent ringIntent = new Intent();
ringIntent.setType("audio/mp3");
ringIntent.setAction(Intent.ACTION_GET_CONTENT);
ringIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(ringIntent, "Select Ringtone"), SELECT_RINGTONE);
Я делаю следующее с URI содержимого:
m_ringerPath = m_ringtoneUri.getPath();
File file = new File(m_ringerPath);
Затем выполните некоторые действия FileInputStream с указанным файлом.
Просто используйте getContentResolver().openInputStream(uri)
, чтобы получить InputStream
из URI.
Вы можете использовать Content Resolver для получения пути file://
из URI content://
:
String filePath = null;
Uri _uri = data.getData();
Log.d("","URI = "+ _uri);
if (_uri != null && "content".equals(_uri.getScheme())) {
Cursor cursor = this.getContentResolver().query(_uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(0);
cursor.close();
} else {
filePath = _uri.getPath();
}
Log.d("","Chosen path = "+ filePath);
Попытка обработать URI с контентом://схема, вызывая ContentResolver.query()
, не является хорошим решением. В HTC Desire, работающем 4.2.2, вы можете получить NULL в качестве результата запроса.
Почему бы не использовать ContentResolver вместо этого? fooobar.com/questions/27349/...
Если у вас есть контент Uri с content://com.externalstorage...
, вы можете использовать этот метод для получения абсолютного пути к папке или файлу на Android 19 или выше.
public static String getPath(final Context context, final Uri uri) {
System.out.println("%%%%%%%%%%%%%%%");
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
System.out.println("getPath() uri: " + uri.toString());
System.out.println("getPath() uri authority: " + uri.getAuthority());
System.out.println("getPath() uri path: " + uri.getPath());
// ExternalStorageProvider
if ("com.android.externalstorage.documents".equals(uri.getAuthority())) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
System.out.println("getPath() docId: " + docId + ", split: " + split.length + ", type: " + type);
System.out.println("%%%%%%%%%%%%%%%");
// This is for checking Main Memory
if ("primary".equalsIgnoreCase(type)) {
if (split.length > 1) {
return Environment.getExternalStorageDirectory() + "/" + split[1] + "/";
} else {
return Environment.getExternalStorageDirectory() + "/";
}
// This is for checking SD Card
} else {
return "storage" + "/" + docId.replace(":", "/");
}
}
}
return null;
}
Вы можете проверить, что каждая часть Uri использует println. Возвращаются значения для моей SD-карты и основной памяти устройства. Вы можете получить доступ и удалить, если файл находится в памяти, но я не смог удалить файл с SD-карты, используя этот метод, только чтение или открытие изображения с использованием этого абсолютного пути. Если вы нашли решение для удаления с помощью этого метода, поделитесь им. SD CARD
getPath() uri: content://com.android.externalstorage.documents/tree/612E-B7BF%3A/document/612E-B7BF%3A
getPath() uri authority: com.android.externalstorage.documents
getPath() uri path: /tree/612E-B7BF:/document/612E-B7BF:
getPath() docId: 612E-B7BF:, split: 1, type: 612E-B7BF
ОСНОВНАЯ ПАМЯТЬ
getPath() uri: content://com.android.externalstorage.documents/tree/primary%3A/document/primary%3A
getPath() uri authority: com.android.externalstorage.documents
getPath() uri path: /tree/primary:/document/primary:
getPath() docId: primary:, split: 1, type: primary
Если вы хотите получить Uri с file:///
после использования пути
DocumentFile documentFile = DocumentFile.fromFile(new File(path));
documentFile.getUri() // will return a Uri with file Uri
Вы должны использовать
getContentResolver().openInputStream(uri)
, чтобы получить InputStream
из URI. Потому что это очень легко и легко понять.
Для более openInputStream(android.net.Uri)