5

I am trying to play an audio file from the internal storage. The code I used is..

package com.abhi.firstapp.firstapp;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.net.URI;

public class MainActivity extends AppCompatActivity {

     MediaPlayer mp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);



    File f= new File("/sdcard/a.mp3");
    if(f.exists())
    {

        Toast toast= Toast.makeText(this, "file exists", Toast.LENGTH_LONG);
        toast.show();
        Log.d("uri","1");
        Uri uri= Uri.fromFile(f);
        Log.d("uri", "2");

        mp= new MediaPlayer();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        Log.d("uri", "3");

        try {
            mp.setDataSource("/sdcard/a.mp3");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //mp.setDataSource(getBaseContext(), uri);
            Log.d("uri", "4");


        try {
            mp.prepare();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("uri", "IOException");
        }

        mp.start();


    }
    else {
        Toast toast1 = Toast.makeText(this, "file does not exist", Toast.LENGTH_LONG);
        toast1.show();
    }

    //MediaPlayer mp= MediaPlayer.create(getBaseContext(), uri);
    //mp.start();

}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

By using the log, I can determine that this code is running till the mp.prepare(mediaplayer prepare). And on this step, it gives the error Illegal State Exception

 Caused by: java.lang.IllegalStateException
   at android.media.MediaPlayer.prepare(Native Method)

Please Help!

Abhishek Kulshrestha
  • 1,373
  • 4
  • 17
  • 31

2 Answers2

12

There are a couple of things you might want to change.

First: mp.prepare() will block your main thread, which is forbidden and will result in an exception where Android will close your app. To prevent this, mp.prepareAsync was designed. Use that method instead and implement both an onPreparedListener and an onErrorListener.

Second: you should provide a datasource before you call prepare().

You could do this for example this way:

public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...

        MediaPlayer mp = new MediaPlayer();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

        try { 
            mediaPlayer.setDataSource(streamURL);
        } catch (IOException e) {
            // Error, do something
        }

        mp.prepareAsync();
        ...
    }
        @Override
    public void onPrepared(MediaPlayer player) {
        mediaPlayer.start();
    }

    ...

}
Cmitz
  • 146
  • 1
  • 4
  • 5
    I see that he did call setDataSource before the prepare in the original code.. So why was the answer accepted? Was the IllegalState due to calling prepare() instead of prepareAsync()? I have a similar problem, and I'm still calling prepare() but I do it from a background thread, so it should work, right? – Gili Garibi Oct 15 '17 at 10:17
  • This answer might be helpful to folks looking here: https://stackoverflow.com/a/53390067/826946 – Andy Weinstein Nov 20 '18 at 09:44
  • What is the usage of"implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener" to the activity if you don't use it. useless – Lasitha Lakmal Jan 20 '20 at 03:22
  • @LasithaLakmal - `@override public void onPrepared(MediaPlayer player)` implements `OnPreparedListener`, which is the interface that is most relevant to this question. – ToolmakerSteve Jun 23 '23 at 19:11
6

I had the same problem. It can be raised because MediaPlayer is already prepared. When you create a new MediaPlayer by MediaPlayer mp = MediaPlayer.create(getContext(),someUri); mp prepares automatically so you should not prepare it by yourself.

ilya_kas
  • 159
  • 1
  • 6