2

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
  • 7,714
  • 10
  • 56
  • 88

4 Answers4

4

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();
Robert Estivill
  • 12,369
  • 8
  • 43
  • 64
3

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

It is not possible to use content from your RES folder outside of the App. The content is inside the App and not reachable from outside the App. If you want to make the content available you have to implement your own ContentProvider returning the data.

@CommonsWare is right. See http://iserveandroid.blogspot.nl/2011/01/how-to-access-resources-from-other.html

userM1433372
  • 5,345
  • 35
  • 38
  • Actually, resources are world-readable, and therefore can be reached by third-party apps. – CommonsWare Jan 24 '13 at 16:00
  • As far as i know you can read resources from other apps. I'm just not sure on how to do it! – caiocpricci2 Jan 24 '13 at 16:01
  • @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? – userM1433372 Jan 25 '13 at 06:32
  • @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. – CommonsWare Jan 25 '13 at 13:49
0

If you just need to set the sound URI on the Notification.Builder, use

 Uri.parse("android.resource://com.my.great.application/"
                        + R.raw.mysound);

where R.raw.mysound can be something like mysoud.ogg in the raw resources folder.

However I am not sure if MP3 is exactly supported. As these are just internal resources of your application, try to convert to OGG.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
  • I don't get it. How exactly is that any different from what i'm trying? – caiocpricci2 Jan 24 '13 at 16:00
  • I know it works, I have tested two minutes ago. The only reason then could be Android device does not support MP3. – Audrius Meškauskas Jan 24 '13 at 16:01
  • 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 Jan 24 '13 at 16:03
  • I say, try to convert to OGG with something like http://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. – Audrius Meškauskas Jan 24 '13 at 16:24