How to play audio file from raw/assets folder on the native/default media player?

13,976

Solution 1

When you call startActivity(), you are trying to start an activity. The Intent you pass to startActivity() indicates what activity -- or selection out of a set of available activities -- you want to start. In your case, you are trying to view an android.resource:// Uri. This is not an http:// Uri, nor an https:// Uri, nor a file:// Uri.

Activities that advertise themselves as supporting operations like this have, in their <intent-filter> a statement of what Uri schemes they support. You are assuming that there is an app, on the user's device, that supports an android.resource:// scheme. Personally, I do not think that this is a safe assumption. http://, https://, and file:// should be safe, and content:// (for a ContentProvider) is fairly likely as well.

For example, the AOSP Music app does not support the android.resource scheme, based on its current manifest contents.

Solution 2

Any reason why don't you use the MediaPlayer directly? You can pass the resource id directly

int resourceId = R.raw.your_media_resource;
MediaPlayer mediaPlayer = MediaPlayer.create( context, resourceId );
mediaPlayer.setOnCompletionListener( new OnCompletionListener()
{
    @Override
    public void onCompletion( MediaPlayer mp )
    {
        mp.release();
    }
} );
mediaPlayer.start();
Share:
13,976
caiocpricci2
Author by

caiocpricci2

Updated on June 04, 2022

Comments

  • caiocpricci2
    caiocpricci2 almost 2 years

    I know i can play an mp3 file in the media player like that:

    Intent intent = new Intent();  
    intent.setAction(android.content.Intent.ACTION_VIEW);  
    File file = new File(YOUR_SONG_URI);  
    intent.setDataAndType(Uri.fromFile(file), "audio/*");  
    startActivity(intent);
    

    Following this link I tried to get the URI like:

    Uri audio = Uri.parse("android.resource://com.audio.test/"+R.raw.audio1);
    Log.d(TAG,"uri:"+audio.toString());
    

    and

    Uri audio = Uri.parse("android.resource://com.audio.test/raw/audio");
    Log.d(TAG,"uri:"+audio.toString());
    

    Which outputs the expected result:

    01-24 15:28:23.190: D/MyClass(30234): uri:android.resource://com.audio.test/2131034112
    01-24 15:29:13.: D/MyClass(30234): uri:android.resource://com.audio.test/raw/audio1
    

    But it doesn't work. The media player does not start. Any ideas why?

    Update

    I included a createChooser and instead of the expected list with players i get a "Unable to find application to perform this action" message. This is my exact code:

     public void playAudio(){
              Intent viewMediaIntent = new Intent();   
              viewMediaIntent.setAction(android.content.Intent.ACTION_VIEW);        
              Uri audio = Uri.parse("android.resource://com.audio.test/raw/"+R.raw.audio1);       
              Log.d(TAG,"uri:"+audio.toString());
              viewMediaIntent.setDataAndType(audio, "video/*");   
              viewMediaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
              Log.d(TAG,"Starting");
              Intent i = Intent.createChooser(viewMediaIntent, "Play Music");
                mGap.startActivity(i);
              Log.d(TAG,"Started");
          }
    

    Update 2

    Thank you @CommonsWare for the explanation. Now I understand why it doesn't work. But the problem remains, can I achieve what I want? Get a Uri of a file stored in the raw/assets folder with a file:// scheme?

    Update 3

    I found a way to do it, although it's not the best it works. I have only 3 files and this doesn't delay the execution at all. I am copying the file from the res/raw to a local directory on the phone and getting the Uri from that file. Any suggestions on how to avoid that step are appreciated.

     public void copyFileToDir(String audioFile){
              File test = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "/" + audioFile + ".mp3");
              if (test.exists()){
                  Toast.makeText(mGap, "Exists", Toast.LENGTH_SHORT).show();
                  return;
              }
              File dest = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
              int i = mGap.getResources().getIdentifier("raw/"+audioFile, "string", mGap.getPackageName());
              InputStream in = mGap.getResources().openRawResource(i);
              // Used the File-constructor
              OutputStream out;
            try {
                out = new FileOutputStream(new File(dest, audioFile + ".mp3"));
                  // Transfer bytes from in to out
                  byte[] buf = new byte[1024];
                  int len;
                  try {
                      // A little more explicit
                      while ( (len = in.read(buf, 0, buf.length)) != -1){
                           out.write(buf, 0, len);
                      }
                  } finally {
                      // Ensure the Streams are closed:
                      in.close();
                      out.close();
                  }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    
    
          }
    
    
          public void playAudio(String audioFile){
              copyFileToDir(audioFile);
              File dest = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "/" + audioFile + ".mp3");
              Uri r = Uri.fromFile(dest);         
              Intent viewMediaIntent = new Intent();   
              viewMediaIntent.setAction(android.content.Intent.ACTION_VIEW);                                 
              viewMediaIntent.setDataAndType(r, "audio/*");   
              viewMediaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);          
              Intent i = Intent.createChooser(viewMediaIntent, "Play Music");
                mGap.startActivity(i);
    
          }
    
          public void playVideo(String movieurl){
              Intent intentToPlayVideo = new Intent(Intent.ACTION_VIEW);
              intentToPlayVideo.setDataAndType(Uri.parse(movieurl), "video/*");
              Log.d(TAG,"Playing:" + movieurl);
              mGap.startActivity(intentToPlayVideo);
          }
    
  • caiocpricci2
    caiocpricci2 over 11 years
    Yes, i don't want to create a UI. I want to play it on whatever media player the user is already using!
  • caiocpricci2
    caiocpricci2 over 11 years
    I don't get it. How exactly is that any different from what i'm trying?
  • CommonsWare
    CommonsWare over 11 years
    Actually, resources are world-readable, and therefore can be reached by third-party apps.
  • caiocpricci2
    caiocpricci2 over 11 years
    As far as i know you can read resources from other apps. I'm just not sure on how to do it!
  • Audrius Meškauskas
    Audrius Meškauskas over 11 years
    I know it works, I have tested two minutes ago. The only reason then could be Android device does not support MP3.
  • caiocpricci2
    caiocpricci2 over 11 years
    Sorry but that still doesn't show me what is different on your code and on mine. Can you please include a larger block of code? How did you make it work?
  • caiocpricci2
    caiocpricci2 over 11 years
    Thank you for the explanation! Even if i can't do it now at least I understand why!
  • Audrius Meškauskas
    Audrius Meškauskas over 11 years
    I say, try to convert to OGG with something like audio.online-convert.com/convert-to-ogg. It is not visible in the code as the file extension is not part of R.raw.resourcename.
  • userM1433372
    userM1433372 over 11 years
    @CommonsWare: Thats new to me. Could you please give an example? Do you have to provide special permissions? Can i access all resources from all applications?
  • CommonsWare
    CommonsWare over 11 years
    @user1433372: "Could you please give an example? " -- see createPackageContext(). "Do you have to provide special permissions?" -- no. "Can i access all resources from all applications?" -- AFAIK, there are no limits.