0

I'm having a bit of trouble playing a .mp3 file from my phone's internal storage. I'm working on this app for a Course I'm following, but I can't seem to figure out why my .mp3 files won't play.

Here's the basic setup of the app:

I have to create a screen with 4 buttons; three that are linked to .mp3 files on the local storage, and one to open up a browser that lets you browse for .mp3 files. On the browse screen, when a file is selected and it's a .mp3, three buttons appear to let you define a new link so the audio can be played.

I am using the file/folder browsing from here: http://custom-android-dn.blogspot.nl/2013/01/create-simple-file-explore-in-android.html, which works perfectly. I can pick up my .mp3 files without a problem, all the way up to the base-path of my internal storage.

I then looked at how I should play audio-files from my storage, here: Play mp3 sounds from SD card (the accepted answer), though I had to tweak it a little, as the file-path was already defined in a different Class.

The code I'm using (class-names defined after the description)..

..To play the audio (MainActivity.java):

if(R.id.mp3_1_btn == b.getId()){
    a.PlayAudio(0);
}

..Function PlayAudio()(Audio.java)

public void PlayAudio(int audioFile){
    mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

    if(AudioArray[audioFile] != ""){
        if(mp != null){
            mp.release();
        }

        try{
            FileDescriptor fd =null;
            FileInputStream fis = new FileInputStream(AudioArray[audioFile]);
            fd = fis.getFD();

            if(fd != null){
                mp.setDataSource(fd);
                mp.prepare();
                mp.start();
                Message("Play");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

..The onCreate of the Browser (FileExplorerActivity.java):

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    currentDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
    fill(currentDir); 
}

..The assigning of audio files to a button (FileExplorerActivity.java):

if(R.id.AssignBtn1 == b.getId()){
    a.setAudioString(0, fullDirectory);
    this.finish();
}

..Things related to fullDirectory (FileExplorerActivity.java/FileBrowser.java)

fullDirectory = data.getStringExtra("GetPath")+"/"+data.getStringExtra("GetFileName");
intent.putExtra("GetPath",currentDir.toString());
intent.putExtra("GetFileName",o.getName());

..Things related to AudioArray (Audio.java)

private static String AudioArray[] = {"", "", ""};
public void setAudioString(int index, String dir){
    AudioArray[index] = dir;
}

And here's the output string from my fullDirectory variable:

/storage/emulated/0/Music/<name>.mp3

I've also got some logs from any errors and messages.

When I assign a .mp3 to a button

08-24 22:44:11.468: D/MediaPlayer(10327): release() in
08-24 22:44:11.468: D/MediaPlayer(10327): release() out
08-24 22:44:11.478: W/System.err(10327): java.lang.IllegalStateException
08-24 22:44:11.478: W/System.err(10327):    at     android.media.MediaPlayer._setDataSource(Native Method)
08-24 22:44:11.478: W/System.err(10327):    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1282)
08-24 22:44:11.478: W/System.err(10327):    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1254)
08-24 22:44:11.478: W/System.err(10327):    at com.example.mp3.Audio.PlayAudio(Audio.java:32)
08-24 22:44:11.478: W/System.err(10327):    at com.example.mp3.MainActivity.onClick(MainActivity.java:53)
08-24 22:44:11.478: W/System.err(10327):    at android.view.View.performClick(View.java:4480)
08-24 22:44:11.478: W/System.err(10327):    at android.view.View$PerformClick.run(View.java:18686)
08-24 22:44:11.478: W/System.err(10327):    at android.os.Handler.handleCallback(Handler.java:733)
08-24 22:44:11.478: W/System.err(10327):    at android.os.Handler.dispatchMessage(Handler.java:95)
08-24 22:44:11.478: W/System.err(10327):    at android.os.Looper.loop(Looper.java:157)
08-24 22:44:11.488: W/System.err(10327):    at android.app.ActivityThread.main(ActivityThread.java:5872)
08-24 22:44:11.488: W/System.err(10327):    at java.lang.reflect.Method.invokeNative(Native Method)
08-24 22:44:11.488: W/System.err(10327):    at java.lang.reflect.Method.invoke(Method.java:515)
08-24 22:44:11.488: W/System.err(10327):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:852)
08-24 22:44:11.488: W/System.err(10327):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:668)
08-24 22:44:11.488: W/System.err(10327):    at dalvik.system.NativeStart.main(Native Method)

When trying to play said .mp3 (this crashes the app, obviously)

08-24 22:45:21.628: W/dalvikvm(10327): threadid=1: thread exiting with uncaught exception (group=0x4170ee18)
08-24 22:45:21.628: E/AndroidRuntime(10327): FATAL EXCEPTION: main
08-24 22:45:21.628: E/AndroidRuntime(10327): Process: com.example.mp3, PID: 10327
08-24 22:45:21.628: E/AndroidRuntime(10327): java.lang.IllegalStateException
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.media.MediaPlayer._setAudioStreamType(Native Method)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.media.MediaPlayer.setAudioStreamType(MediaPlayer.java:2135)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at com.example.mp3.Audio.PlayAudio(Audio.java:18)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at com.example.mp3.MainActivity.onClick(MainActivity.java:53)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.view.View.performClick(View.java:4480)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.view.View$PerformClick.run(View.java:18686)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.os.Handler.handleCallback(Handler.java:733)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.os.Handler.dispatchMessage(Handler.java:95)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.os.Looper.loop(Looper.java:157)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at android.app.ActivityThread.main(ActivityThread.java:5872)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at java.lang.reflect.Method.invokeNative(Native Method)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at java.lang.reflect.Method.invoke(Method.java:515)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:852)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:668)
08-24 22:45:21.628: E/AndroidRuntime(10327):    at dalvik.system.NativeStart.main(Native Method)

So, we finally come to the question:

What is wrong with my code, and how do I fix it? Should I try a different approach, or did I miss something?

I hope someone can help me with this. And if someone wants me to put my project on Dropbox and post a link, be sure to ask and I'll gladly comply.

Community
  • 1
  • 1
Zubaja
  • 251
  • 3
  • 18

1 Answers1

1

Another approach is an audio service:

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;

public class AudioService extends Service {
    MediaPlayer _player;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        _player = MediaPlayer.create(this, R.raw.someaudio);
        //where someaudio (someaudio.mp3) is the raw resource id for the resource to use as the datasource

        // or _player = MediaPlayer.create(this, ... uri ...);
        // where uri is the Uri from which to get the datasource

        // see http://developer.android.com/reference/android/media/MediaPlayer.html

        _player.setLooping(false);
    }

    @Override
    public void onDestroy() {
        if (_player.isPlaying()) {
            _player.stop();
        }

        _player.release();
        _player = null;
    }

    @Override
    public void onStart(Intent intent, int startid) {
        _player.start();
    }
}

To call the service in a MainActivity:

startService(new Intent(this, AudioService.class)); // start service to play mp3 file

// to stop playing: stopService(new Intent(this, AudioService.class));
user3806621
  • 278
  • 1
  • 6
  • Thanks for the reply. I'll look into it when I return from work; I was actually planning on looking at it this morning, but I ran out of time. It's also a good thing this method supports Uri, as it hás to be a file directly from the internal storage, not in the /res/raw/ folder. – Zubaja Aug 25 '14 at 05:22
  • I've tried your method, created the AudioService, tweaked my code, still got the paths right, but no audio. This is my code when pressing a button to play an MP3 now: `if(R.id.mp3_1_btn == b.getId()){ setAudioIndex(0); startService(new Intent(this, AudioService.class)); }` – Zubaja Aug 25 '14 at 21:44
  • Forgot to mention, I tried putting a Log and a Message() inside the onCreate of the AudioService, but it never goes there. I tried making a Class variable **(AudioService a = new AudioService())**, but that didn't work either. And neither does it go into the **onStart** function. – Zubaja Aug 25 '14 at 21:53
  • Did you try to put any mp3 file in a Raw resource and check a service? – user3806621 Aug 26 '14 at 16:20
  • To make service working, please add this line to your AndroidManifest.xml file: , somewhere inside of tag. – user3806621 Aug 27 '14 at 01:10
  • Also make sure there is a permission right to read-write an external storage in the same manifest file: and . – user3806621 Aug 27 '14 at 01:16
  • Many thanks! I forgot to add , now my audio plays. – Zubaja Aug 27 '14 at 17:21