Null Pointer Exception when calling mediaPlayer.start() : Android - android

Basically what I want is to allow the user to select a audio file from their device and once they do, this activity starts and the music/audio file will be played. For that I've used included an intent-filter in my Android Manifest File, and its working fine, there are no errors.
The problem is when I call mediaPlayer.start() I get a Null Pointer Exception. From what I've read so far, this happens because MediaPlayer fails to create a object or something... the MediaPlayer.cretae() returns null.
The following is the whole code for this Activity:
public class IntentPlayerActivity extends AppCompatActivity {
TextView song_name,artist_name;
ImageView playPauseBtn;
SeekBar seekBar;
static Uri uri;
static MediaPlayer mediaPlayer = new MediaPlayer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent_player);
initViews();
Intent intent = getIntent();
if (intent.getAction().equals(Intent.ACTION_VIEW)){
Log.d("Intent Player_Activity:", " File Path: "+ intent.getData().getPath());
playPauseBtn.setImageResource(R.drawable.ic_pause_circle_outline);
uri = Uri.parse(intent.getData().getPath());
Log.d("Intent Player_Activity:", " URI: "+uri.toString());
if (mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = MediaPlayer.create(getApplicationContext(),uri);
mediaPlayer.start();
}else {
mediaPlayer = MediaPlayer.create(getApplicationContext(),uri);
mediaPlayer.start();
}
}
}
private void initViews() {
song_name = findViewById(R.id.song_name);
artist_name = findViewById(R.id.song_artist);
playPauseBtn = findViewById(R.id.play_pause);
seekBar = findViewById(R.id.seekBar);
}
}
I'm hopping someone could explain what MediaPlayer.create() dose and what could be causing it to fail, for my case I don't believe the audio file is an invalid format or the specified media file cannot be found. I think its something else.

Delete:
uri = Uri.parse(intent.getData().getPath());
Instead, pass intent.getData() to MediaPlayer.create():
mediaPlayer = MediaPlayer.create(getApplicationContext(),intent.getData());

Related

AndroidMediaplayer.create freeze (still running but dont do anything) the App

I was using MediaPlayer to play sounds in my App but from Its start to freeze the App:
Thats the code where I call create method. I moved the code inside an AsyncTask class :
public class BackgroundSound extends AsyncTask<Integer,Void,Void> {
MediaPlayer mpB;
MediaPlayer mpG;
Context ctx;
BackgroundSound(Context appctx)
{
ctx = appctx;
}
#Override
protected Void doInBackground(Integer... Params) {
switch (Params[0]){
case 0:
mpB = MediaPlayer.create(ctx, R.raw.sonidoemocion5sec);
mpB.setLooping(true);
mpB.setVolume(0.75f, 0.75f);
mpB.start();
break;
case 1:
if (mpG != null)
{
mpG.release();
mpG = null;
}
mpG = MediaPlayer.create(ctx, R.raw.ganador);
mpG.setVolume(1, 1);
mpG.start();
break;
case 2:
if (mpG != null){
mpG.release();
mpG = null;
}
mpG = MediaPlayer.create(ctx, R.raw.perder);
mpG.setVolume(1, 1);
mpG.start();
break;
}
return null;
}
}
Debuging I find that the freeze (app still running but dont make anything) occurred in the new line inside the method create from MediaPlayer.java file::
public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder,
AudioAttributes audioAttributes, int audioSessionId) {
try {
MediaPlayer mp = new MediaPlayer();
I don't understand what's going on. Any tips?
The warn & Error Log exits:
Instead of using MediaPlayer.create(), use mp.setDataSource() method so that you can call mp.prepareAsync() and then set listener to listen for its completion like this:
mp.setDataSource(this, audioUri);
mp.prepareAsync();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
Now for this audioUri object of Uri, you can set it to your audio files in the raw folder by having this line of code in your project:
audioUri = Uri.parse("android.resource://com.yourpackagename/" + R.raw.your_audiofile_name);
This method prepares the mp asynchronously and doesn't block the UI
There are two possible solutions for this issue, but it is not sure that it will work properly as I have not tested it.
Solution 1.
Replace below line:
audiojuego = MediaPlayer.create(this, R.raw.sonidoemocion);
with:
audiojuego = MediaPlayer.create(getApplicationContext(), R.raw.sonidoemocion);
//As you are calling from doInBackground() method, this will not work properly.
Solution 2.
Initialize media player by your own way instead of default.
Uri url=Uri.parse("android.resource://"+getPackageName()+"/raw/sonidoemocion");
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();

Android : Not able to stop the audio from the same button

I'm working on an app in which there is a grid layout with 8 buttons and each attached to a sound. Now I'm able to play the audio on the click of a button but when I press the same button again the audio doesn't stop.
All my buttons are attached to a common onClick method and the class file retrieves the id of the button and matches with the sound file present in the raw folder.
I'm using a flag for this but don't know where I'm going wrong.
My Code
boolean play = true;
MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonTapped(View view)
{
int id = view.getId();
String ourID = "";
ourID = view.getResources().getResourceEntryName(id);
int resourceID = getResources().getIdentifier(ourID, "raw", "com.starprojects.gridlayoutdemo");
mediaPlayer = MediaPlayer.create(this,resourceID);
if(play)
{
mediaPlayer.start();
play = false;
}
else {
// mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
// play = true;
}
// mediaPlayer = null;
Log.i("button tapped",ourID);
}
}
define mediaPlayer outsite of function, then do that
public void buttonTapped(View view) {
int id = view.getId();
String ourID = "";
ourID = view.getResources().getResourceEntryName(id);
int resourceID = getResources().getIdentifier(ourID, "raw", "com.starprojects.gridlayoutdemo");
stopPlayer();
mediaPlayer = MediaPlayer.create(this,resourceID);
if (mediaPlayer != null)
mediaPlayer .start();
}
public void stopPlayer() {
if (mediaPlayer != null) {
mediaPlayer .stop();
mediaPlayer .release();
}
mediaPlayer = null;
}
thats all :)
This may or may not be related to your problem, but don't forget to call
mediaPlayer.release();
mediaPlayer = null;
when you are finished. If you do not, resources get built up and start affecting sound outside of the app. Keep in mind a new MediaPlayer is being allocated every time you press the button. I have done this in a previous app and the sound stopped working after a few minutes.
Let me know if this changes anything.
As a matter of fact, you can try making your MediaPlayer a member of the class (defined outside the function) since you only need one sound playing at once. If it isn't null or .isPlaying(), release it. Otherwise, create and play.

Why does MediaPlayer cause errors when used outside onCreate

I'm using a small 2 second sound effect attached to a button. When clicked, the sound effect plays and the user is taking to the next activity. The function I created is outside onCreate and uses Intent to send the user to the next activity. When I add the mp variables I get an error saying there's a problem with playGame(). What is causing the MediaPlayer to not play when it's placed in this function? Eclipse suggests changing mp.create() to MediaPlayer.create but that doesn't fix the issue.
public class SplashScreenActivity extends ActionBarActivity {
public MediaPlayer mp;
public void playGame(View view) {
mp.create(this, R.raw.bulletricochet);
mp.start();
// Do something in response to button
Intent intent = new Intent(this, QuizActivity.class);
startActivity(intent);
}
public void playRules(View view) {
Intent intentR = new Intent(this, RulesActivity.class);
startActivity(intentR);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
}}
Your mp object is null and yet you are calling create method on it.
To create a MediaPlayer object use MediaPlayer.create. You say you tried it but probably didn't assign the return value to your mp variable.
mp = MediaPlayer.create(this, R.raw.bulletricochet);

Starting Activity when video is finished playing

In my Android app, I am trying to simply go back to my main Activity once a video that I am playing ends. I have tried many workarounds, but I can't find a way to call StartActivity from the video onCompletionListener - I am getting the "cannot make a static reference to the non-static method startActivity(Intent) from the type Activity" error.
I tried getting a context from the Activity that preceded the videoView, and passing that to the intent/startActivity. That allowed the app to compile, but then I got a runtime exception.
Here is the code as it stands now, which gets the "cannot make a static reference" error - any help would be appreciated!
public class Videoscreen extends Activity{
public static VideoView myVideoView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoplay);
myVideoView = (VideoView) findViewById(R.id.main_videoview);
System.out.println("playing video oncreate");
playVideo();
}
public static void playVideo(){
// video finish listener
myVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer vmp) {
Intent intent = new Intent();
intent.setClass(Videoscreen.this, Game.class);
Videoscreen.startActivity(intent);
}
});
String low_word = SpellingView.get_low_word();
Uri bubblesUri = Uri.parse("android.resource://org.lalloinc.ilovetrucks/raw/"+ low_word + "_vid");
myVideoView.setVideoURI(bubblesUri);
myVideoView.start();
}
}
If you know the time of the video then you try:
String uri1 = "android.resource://" + getPackageName() + "/" + R.raw.race3;
vd.setVideoURI(Uri.parse(uri1));
vd.start();
new Thread() {
public void run() {
try{
sleep(50000);
} catch (Exception e) {
}
Intent intent = new Intent(Video.this, Another.class);
startActivity(intent);
finish();
}
}.start();
if you don't know the time then you get the time as:
int vtime = vd.getDuration();
And then at thread sleep you just put this integer.
If you started the Video Activity from the Activity you would like to go back to later, just calling finish() at the end of the video will do the job.
Starting the main Activity again creates a not necessarily wanted stack of activities.

Create() fails in MediaPlayer - android

I am trying to play a few music (wav format) files based on button clicks. I am unable to get MediaPlayer to work properly. Every time I try to instantiate an object of MediaPlayer class, it fails on create(). Before I post the code, here is a run-through of what I am doing:
1. A layout file that contains 2 buttons.
2. Those buttons are read and onClickListeners defined for them.
3. Depending on the button clicked, a function called playAudioFile(View) called which creates the MediaPlayer instance and plays the file. The code for playAudioFile(View) is as follows:
public void playAudioFile(View v) {
/*Steps:
* 1. Take in id of the button.
* 2. Using id, identify what file needs to be played.
* 3. Play file.
*/
String path_to_file = null; //this is the path to the file.
if(b01.getId() == ((Button)v).getId()) {
Log.v(this.toString(), "Button 01 pressed.");
path_to_file = "/sdcard/audio/temp1.wav";
} else if(b02.getId() == ((Button)v).getId()) {
Log.v(this.toString(), "Button02 pressed.");
path_to_file = "/sdcard/audio/temp2.wav";
}
path_to_file = "file://" + path_to_file;
Uri streamUri = Uri.parse(path_to_file);
Log.v(this.toString(), "Path of file = " + path_to_file);
MediaPlayer mp = MediaPlayer.create(this, streamUri);
if(mp == null) {
Log.v(this.toString(), "Create() on MediaPlayer failed.");
}
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
try {
mp.start();
} catch (IllegalStateException e) {
e.printStackTrace();
Log.v(this.toString(), "Illegal state exception thrown in start.");
}
}
});
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
}
I have gone through a lot of posts here on stackoverflow that detail solutions to the above problem. I am encountering this problem after having incorporated all the suggestions made therein. Any help is most welcome.
Thanks,
Sriram
I dont understand why you are trying to do
MediaPlayer mp = MediaPlayer.create(this, streamUri);
This is my implementation of my Player, Hope this will help you in some way:
MediaPlayer mp = new MediaPlayer();
setContentView(R.layout.player);
Intent intent = getIntent();
String path = "";
System.out.println("My Scheme : "+intent.getData().toString().substring(8));
if (intent.getData().getScheme().equals("video")) {
path = intent.getData().toString().substring(8);
System.out.println("Path : "+path);
if(path.endsWith(".mp3")) {
setContentView(R.layout.musicplayer);
setContentView(R.layout.controls);
Log.e("MusicPlayer", "Playing: " + path);
try {
Notification notification = new Notification(
R.drawable.playbackstart, path, System.currentTimeMillis());
nm.notify(NOTIFY_ID, notification);
mp.reset();
mp.setDataSource(path);
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
System.out.println("Hi i am at the End");
}
});
}catch {expression}
If I'm not wrong, you can't use onPrepare because mp.prepare() is called inside MediaPlayer.create(). The simpliest code can be something like this:
MediaPlayer mp = MediaPlayer.create(this, streamUri);
mp.start();
If you want something more elaborated, you can try this:
MediaPlayer mp = MediaPlayer.create(this, streamUri);
if(mp == null) {
Log.v(this.toString(), "Create() on MediaPlayer failed.");
} else {
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//here you should call the methods to release memory
mp.stop();
mp.release();
}
});
mp.start();
}
Tell me if it helped you.
PD: Is better if you use a device for testing rather than a simulator. Some classes don't work properly there (MediaPlayer can't reproduce video in simulators) and I don't remember if it supports audio.
As far as I understand your problem: You are calling the MediaPlayer.create(...) method, and it returns null, meaning the creation of a MediaPlayer instance failed. According to the accepted answer of this post MediaPlayer.create() always returns null it is due to a corrupted audio file.
I also have an issue, where the sound gets played but on rare occasions the create() method also returns null. I use sounds in a turn based game, after each turn a sound is played. I always call the create method, start the player and release it when it's done. That happens every turn and like once in 300 turns the create method returns null... So in my case it must be something else. In yours it could probably have something to do with the corruption of the mp3 file.

Categories

Resources