How to play audio file from raw/assets folder on the native/default media player?
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();
caiocpricci2
Updated on June 04, 2022Comments
-
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 over 11 yearsYes, i don't want to create a UI. I want to play it on whatever media player the user is already using!
-
caiocpricci2 over 11 yearsI don't get it. How exactly is that any different from what i'm trying?
-
CommonsWare over 11 yearsActually, resources are world-readable, and therefore can be reached by third-party apps.
-
caiocpricci2 over 11 yearsAs far as i know you can read resources from other apps. I'm just not sure on how to do it!
-
Audrius Meškauskas over 11 yearsI know it works, I have tested two minutes ago. The only reason then could be Android device does not support MP3.
-
caiocpricci2 over 11 yearsSorry 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 over 11 yearsThank you for the explanation! Even if i can't do it now at least I understand why!
-
Audrius Meškauskas over 11 yearsI 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 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 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.