Получить URI файла .mp3, хранящегося в папке res/raw в Android

У меня есть много файлов .mp3, хранящихся в папке res/raw.

Я получаю URI файла .mp3, используя следующий код.

Uri.parse("android.resource:///com.my.android.sharesound/"+resId);

Это возвращает: android.resource:///com.my.android.sharesound/2130968609

Теперь я использую этот URI при создании Share Intent

    shareIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse("android.resource://com.my.android.sharesound/"+resId));
    startActivity(Intent.createChooser(shareIntent,"Share Sound");

Когда я выбираю любое почтовое приложение, например. Gmail или YahooMail из общего намерения, файл mp3 успешно прикреплен. Но это показывает, что 2130968609 (в приложении)

я не хочу, чтобы resourceId (2130968609) появлялся.

Я хочу отобразить имя файла.mp3

Как я могу это сделать? Я что-то упускаю ?

OR

Есть ли другой способ прикрепить файл .mp3, хранящийся в res/raw, к почте через Share Intent.


person Kartik Domadiya    schedule 02.11.2011    source источник


Ответы (7)


Наконец, после долгих поисков я нашел решение.

Если вы хотите получить URI любого ресурса, есть два способа:

  1. Использование имени ресурса

    Синтаксис: android.resource://[package]/[res type]/[res name]

    Пример: Uri.parse("android.resource://com.my.package/drawable/icon");

  2. Использование идентификатора ресурса

    Синтаксис: android.resource://[package]/[resource_id]

    Пример: Uri.parse("android.resource://com.my.package/" + R.drawable.icon);

Это были примеры получения URI любого файла изображения, хранящегося в папке с возможностью рисования.

Точно так же вы можете получить URI папки res/raw.

В моем случае я использовал 1-й способ, т.е. Использование имени ресурса

person Kartik Domadiya    schedule 02.11.2011
comment
Спасибо за ответ. ИМО, я думаю, что второй способ был бы предпочтительнее, так как переименование ресурса и т. Д. Можно легко реорганизовать. Следовательно, я выбрал это. - person Dheeraj Bhaskar; 11.01.2013
comment
чтобы помочь рефакторингу, вы также можете заменить имя пакета на Context.getPackageName() - person Richard Le Mesurier; 20.06.2014
comment
О, просто чтобы продолжить веселые лакомые кусочки, вы можете использовать File.separator вместо жесткого кодирования /. И вы можете сойти с ума с File.pathSeparator вместо жесткого кодирования :. Кроме того, отличный ответ! - person Anonsage; 07.11.2014
comment
Спасибо за отличный ответ ... Я выбрал 2 пути. - person Noundla Sandeep; 29.12.2015
comment
Если вы хотите использовать этот URL-адрес в WebView, по крайней мере, в Lollipop (я не пробовал другие версии), вам нужно установить собственный WebViewClient, который обрабатывает эти URL-адреса, примерно так: public WebResourceResponse shouldInterceptRequest(WebView view, String url) { if (url.startsWith(ContentResolver.SCHEME_ANDROID_RESOURCE + "://")) { int idPos = url.lastIndexOf('/'); int id = Integer.parseInt(url.substring(idPos + 1)); return new WebResourceResponse("text/html", "", resources.openRawResource(id)); } return null; } - person ChristophK; 30.06.2016
comment
@KyleJahnke Как вы решили это в Lollipop, несколько пунктов в правильном направлении будут оценены. - person Mudassir; 03.10.2018
comment
У меня есть случай, что есть 2 локализованные папки с сырыми файлами, по умолчанию raw и raw-en. В настройках моего устройства используется английский язык. Когда я делюсь файлом через намерение: sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(android.resource:// + this.getPackageName() + /raw/ + name)); он всегда предоставляет общий доступ к файлу в формате raw-en (может зависеть от настроек устройства). Есть ли способ предоставить общий доступ к конкретному файлу в папке raw независимо от настроек устройства? - person Think Twice Code Once; 23.07.2021

Это работает как по волшебству: если предположить, что mp3 сохранен в необработанной папке как

уведомление_звук.mp3

тогда просто это работает:

Uri uri=Uri.parse("android.resource://"+getPackageName()+"/raw/notification_sound");
person Andrew Sam    schedule 02.06.2016

Не создавайте строку самостоятельно, используйте Uri.Builder:

/**
 * @param resourceId identifies an application resource
 * @return the Uri by which the application resource is accessed
 */
internal fun Context.getResourceUri(@AnyRes resourceId: Int): Uri = Uri.Builder()
    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
    .authority(packageName)
    .path(resourceId.toString())
    .build()

Из AOSP-DeskClock.

person Dewey Reed    schedule 30.08.2019

Вот некоторые методы, которые могут помочь кому-то:

    public Uri getRawUri(String filename) {
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + File.pathSeparator + File.separator + getPackageName() + "/raw/" + filename);
    }
    public Uri getDrawableUri(String filename) {
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + File.pathSeparator + File.separator + getPackageName() + "/drawable/" + filename);
    }
    public Uri getMipmapUri(String filename) {
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + File.pathSeparator + File.separator + getPackageName() + "/mipmap/" + filename);
    }

Просто вызовите метод следующим образом:

Uri rawUri = getRawUri("myFile.filetype");
person Community    schedule 28.03.2018
comment
ContentResolver, getPackageName() ??? какой импорт, чтобы заставить их работать? - person Dao Seeker; 20.02.2020
comment
контекст - context.getPackageName() - person Evgenii Vorobei; 07.03.2020
comment
вам нужен дополнительный File.separator после File.pathSeparator - person Someone Somewhere; 19.06.2020

Однострочный ответ

RingtoneManager.getRingtone(getContext(),Uri.parse("android.resource://com.my.package/" + R.raw.fileName)).play();
person Radesh    schedule 10.07.2018

Вот чистый способ получить любой ресурс,

 Uri.parse(String.format("android.resource://%s/%s/%s",this.getPackageName(),"resource_folder_name","file_name"));
person Remario    schedule 06.04.2017

Попробуйте сохранить файл на SD-карту и, возможно, затем отправить новый URI,

 public boolean saveAs(int resSoundId){
 byte[] buffer = null;
 InputStream fIn = getBaseContext().getResources().openRawResource(resSoundId);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

 String path = "/sdcard/yourapp/temp/";
 String filename = "filename"+".mp3";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }    

Не забудьте удалить файл после успешной отправки электронного письма.

person Reno    schedule 02.11.2011
comment
Спасибо Рено. Но не думаете ли вы, что потребуется некоторое время, чтобы записать файл на SD-карту, получить uri и затем удалить его. ?.. Удаление создаст мне проблему. Когда я должен удалить файл?. Мы не можем предсказать приложения Share Intent. результат. - person Kartik Domadiya; 02.11.2011
comment
Правда, это всего лишь обходной путь, на случай, если вы ничего не получите. Удалите временный каталог, когда ваше приложение закроется. - person Reno; 02.11.2011
comment
@Kartik Попробуйте это решение, у кого-то оно сработало. - person Reno; 02.11.2011
comment
в порядке. я думаю, что нет другого способа получить URI res. У меня другой вопрос, но связанный только с этим. Когда я выбираю любое почтовое приложение, файл прикрепляется. Но когда я выбираю WhatsApp, он просит меня выбрать контакт, но не показывает прикрепленный файл. - person Kartik Domadiya; 02.11.2011
comment
Я действительно не знаю, как WhatsApp обрабатывает их намерения вложения, и да, выберите любой удобный вариант. - person Reno; 02.11.2011
comment
У меня это работает: см. мой ответ stackoverflow.com/questions/7976141/ - person Kartik Domadiya; 02.11.2011