Android: получение URI файла из URI содержимого?
в моем приложении пользователь должен выбрать аудиофайл, который затем обрабатывает приложение. Проблема в том, что для того, чтобы приложение делало то, что я хочу, чтобы оно делало с аудиофайлами, мне нужно, чтобы URI был в формате файла. Когда я использую собственный музыкальный плеер Android для поиска аудиофайла в приложении, URI-это URI контента, который выглядит следующим образом:
content://media/external/audio/media/710
однако, используя популярное приложение файлового менеджера Astro, я получаю следующее:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
последнее намного более доступным для меня, но, конечно, я хочу, чтобы приложение имело функциональность с аудиофайлом, который пользователь выбирает независимо от программы, которую они используют для просмотра своей коллекции. Так что мой вопрос в том, есть ли способ преобразовать content:// стиль URI в file:// URI? В противном случае, что бы вы порекомендовали мне для решения этой проблемы? Вот код, который вызывает выбор, для справки:
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);
Я делаю следующее содержание Ури:
m_ringerPath = m_ringtoneUri.getPath();
File file = new File(m_ringerPath);
затем сделать некоторые FileInputStream вещи с указанным файлом.
6 ответов:
вы можете использовать распознаватель содержимого, чтобы получить
file://путь отcontent://URI: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 с помощью content: / / scheme, вызвав
ContentResolver.query()Это не очень хорошее решение. В HTC Desire под управлением 4.2.2 вы можете получить NULL в результате запроса.почему бы не использовать ContentResolver вместо? https://stackoverflow.com/a/29141800/3205334
если у вас есть Uri контента с
content://com.externalstorage...вы можете использовать этот метод, чтобы получить абсолютный путь к папке или файлу на Android 19 или выше.public static String getPath(final Context context, final Uri uri) { 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); // 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-карты используя этот метод, только чтение или opene D изображение, используя этот абсолютный путь. Если у вас есть найти решение для удаления с помощью этого метода, пожалуйста, поделитесь. SD-КАРТА
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
Ну я немного опоздал ответить,но мой код проверен
проверьте схему от uri:
byte[] videoBytes; if (uri.getScheme().equals("content")){ InputStream iStream = context.getContentResolver().openInputStream(uri); videoBytes = getBytes(iStream); }else{ File file = new File(uri.getPath()); FileInputStream fileInputStream = new FileInputStream(file); videoBytes = getBytes(fileInputStream); }в приведенном выше ответе я преобразовал uri видео в массив байтов , но это не связано с вопросом, Я просто скопировал мой полный код, чтобы показать использование
FileInputStreamиInputStreamкак работает мой код.я использовал переменный контекст, который является getActivity () в моем фрагменте и в Activity это просто ActivityName.это
context=getActivity();/ / in Фрагмент
context=ActivityName.this;// в деятельности
вы должны использовать
getContentResolver().openInputStream(uri)для полученияInputStreamиз URI. Потому что это очень легко и легко понять. Для большегоopenInputStream(android.net.Uri)
Comments