nulll pointer exception for pause method in Mediaplayer for android - android

I keep getting null pointer exceptions for methods of MediaPlayer. I was finally able to get the play function to work by moving the code for play and initialize of play functions into a separate method and call that method from inside the onClick listener.
However am still getting null pointer exception for the apps pause function. I am using pause method of media player. How to the get pause to work? I think the problem is somewhere in the structure of my code and how it is organized.
I tried moving the initialization of the Media player to a different place in the code. and and nothing seems to work. Any ideas?
// onclick listener for the playing the selected song
playB.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
playSong();
}
});
// onclick listener for pausing the song that is playing
pauseB.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pauseSong();
}
});
// method to pause song
public void pauseSong(){
player.pause();
length = player.getCurrentPosition();
}
// method to play song and initialize the MediaPlayer class with one file
// from the drawable folder, need to initialize with something or it will be null
// for that i decided to use an mp3 in R.raw folder
public void playSong(){
// Play song
MediaPlayer player = MediaPlayer.create(this, R.raw.g2);
player.reset();
try {
player.setDataSource(selectedAudioPath);
player.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
player.seekTo(length);
player.start();
} // play method

You have to make a MediaPlayer player global variable. player is not visible for the pauseSong() method therefore you have nullPointerException. Create a MediaPlayer player in your main class and then in onPlaySong() initialize it only like this:
player = MediaPlayer.create(this, R.raw.g2);

Related

Audio file in application doesn't stop on click, it starts playing again

So I put an audio file in my application and it's supposted play when I touch the button and stop when I touch it again.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button one = (Button) findViewById(R.id.buttonId);
final MediaPlayer mp = new MediaPlayer();
one.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
if(mp.isPlaying())
{
mp.stop();
}
try {
mp.reset();
AssetFileDescriptor afd;
afd = getAssets().openFd("mosq.mp3");
mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
mp.prepare();
mp.setLooping(true);
mp.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
here is my code, this part:
if(mp.isPlaying())
{
mp.stop();
}
didn't work for some reason.
Make sure you put a return statement below mp.stop().
From what I can understand the sound does stop but then it starts again because the next part of the code still gets executed
As George D correctly pointed out, you start the media playing unconditionally, even if you just stopped it. You could use his solution or do something like:
if(mp.isPlaying())
{
mp.stop();
}
else {
try {
mp.reset();
AssetFileDescriptor afd;
afd = getAssets().openFd("mosq.mp3");
mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
mp.prepare();
mp.setLooping(true);
mp.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
This has several other potential bugs in it:
* I'm not sure if this is what you intended but the player won't ever pause, just stop and restart from the beginning. If you try to resume or play again it'll completely reload the audio file every time. At a minimum this is a waste of resources, plus it's likely not the expected behavior from a UI perspective.
* You don't want to define the MediaPlayer object as a local variable within the OnCreate method. The only reason this works at all is you have a memory leak (you never unsubscribe your event handler for the click); if you didn't have the memory leak the object would become eligible for garbage collection as soon as you completed the onCreate method and, as far as the framework was concerned, it would no longer exist.

how to clear surface holder when media player is finished?

I made a video player with surfaceview and mediaplayer.
i have 10 videos and 10 buttons.
if click on each buttons, each videos are playing.
here is my code..
//onCreate
holder = surfaceview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//Button1
if(mp == null)mp = new MediaPlayer();
mp.setDataSource(mediaplay_path);
mp.setDisplay(holder);
mp.setScreenOnWhilePlaying(true);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare();
mp.start();
//Button2
if(mp != null){
mp.stop();
mp.reset();
}
mp.setDataSource(mediaplay_path2);
mp.setDisplay(holder);
mp.setScreenOnWhilePlaying(true);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare();
mp.start();
//Button3~Button10 is same as Button2..
everything is fine.
my custom videoview is working alright.
but when the video turns to the next, the last scene of the previous video is remain for a while and turns to the next video scene.
i think it's because the previous surfaceview should be clear before next video is playing.
but i have no idea how to clear the surfaceview or surface holder.
i've searched for this but only could find how to play the video, not how to clear the surfaceview which is set the disaply from mediaplayer.
please help me~~!
Took me two weeks to figure this out. By setting the surfaceholder to TRANSPARENT, Android will destroy the surface. Then setting it back to OPAQUE creates a new surface "clearing" the surface. Note surfacecreate and surfacedestroy events will fire, so if you have code there, beware. I put a imageview set to black to give it a black background. There maybe better ways for that.
private void playVideoA() {
imageViewBlack.bringToFront();
surfaceHolder.setFormat(PixelFormat.TRANSPARENT);
surfaceHolder.setFormat(PixelFormat.OPAQUE);
surfaceView.bringToFront();
mediaPlayerA.setDisplay(surfaceHolder);
//surfaceView.setAlpha((float) 0.01);
mediaPlayerA.start();
};
private void prepareVideoA(String url) {
try {
mediaPlayerA = new MediaPlayer();
mediaPlayerA.setDataSource(url);
mediaPlayerA.prepareAsync();
mediaPlayerA.setOnPreparedListener(this);
mediaPlayerA.setOnCompletionListener(this);
mediaPlayerA.setOnBufferingUpdateListener(this);
mediaPlayerA.setOnInfoListener(this);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
#Override
public void onPrepared(MediaPlayer mp) {
playVideoA()
}
video.getHolder().setFormat(PixelFormat.TRANSPARENT);
video.getHolder().setFormat(PixelFormat.OPAQUE);
video.setVideoURI(Uri.parse(temp));
video.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
it work for me
The SurfaceHolder has lockCanvas methods that will allow you to draw directly to the Surface. Use the drawColor method of the Canvas to fill it with black.
That said, it may be preferable to remove the SurfaceView (as suggested by smile2you), because that should destroy the Surface altogether and free up unused resources. And definitely make sure you are calling release on the MediaPlayers after they are done with playback. Holding on to too many video resources will crash your app.
may be you can use removeView to remove the old custome videoview ,then add the new view
surfaceview.setVisibility(View.GONE);

IllegalStateException when calling AudioRecord.start()

I'm using AudioRecorder to record short audio clips but I'm getting IllegalStateException when calling AudioRecord.start() I've been looking for hours but can't find the cause of this...
I've set Audio Rec + Write External Storage permissions.
Here's a piece of my code:
// main activity...
// Audio inits
final MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getTempPath());
...
// called the sound rec async
new SoundComponent(tvmic, pb, tb).execute(recorder);
// SoundComponent.java
// Getting IllegalStateException when calling recorder[0].start();
[..]
protected Long doInBackground(MediaRecorder... recorder) {
try {
recorder[0].prepare();
} catch (IOException e) {
Log.e("100", "prepare() failed");
}
while (tb.isChecked())
{
//publishProgress();
//recorder[0].prepare();
recorder[0].start(); // here it were it throws
try {
Thread.sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// int amplitude = recorder[0].getMaxAmplitude();
recorder[0].stop();
}
// TODO Auto-generated method stub
return null;
}
[..]
public String getTempPath() // audio temp path
{
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
path+="/temp/audiorectemp.3gp";
return path;
}
Starting and stopping the MediaRecorder multiple times in a loop probably isn't a good idea. Look closely at what you're doing, I've trimmed your code to make it easier to see...
while (tb.isChecked())
{
recorder[0].start(); // here it were it throws
// Sleep here
recorder[0].stop();
}
It probably isn't throwing an exception the first time you call start() but it will on the second loop. See the state machine diagram...MediaRecorder
Also, to detect when the doInBackground(...) thread should be exited, ther is a method on AsyncTask which can be called from the UI thread to cancel it.
The loop should ideally be while (!isCancelled()) and you should call the AsyncTask.cancel(...) method from the onCheckedChanged listener of tb in the main Activity code (assuming tb is a CheckBox or some other CompoundButton).

android media player local object many different sounds should I release?

in one activity I have 5 buttons. Each of these buttons make a different sound.
atm I'm doing on each buttonClicked method:
MediaPlayer mp = MediaPlayer.create(this, R.raw.click);
if(mp != null) mp.start();
MediaPlayer mp = MediaPlayer.create(this, R.raw.click2);
if(mp != null) mp.start();
etc..
is this the right way to do it, and I wonder since mp is local object, doesn't it die when the method dies, ergo no need to call mp.release() ?
note: my sounds are 0.5 sec or less and they seem to complete more often than not (haven't tested in many devices though). I'm targeting 2.1+
You need to declare your Mediaplayer reference globally need to assign mediaplayer object in the onCreate() then in button click call MediaPlayer.create(this/getApplicationContext(),R.Raw.yourfile); follow http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram
mp.reset();
mp=MediaPlayer.create(getApplicationContext(),R.raw.hummingbird);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();

App forces down suddently

i have created a music app.the app has 16 music btns.the app is running with no problem but as i press the btns many times the app forces down..
super.onCreate(icicle);
setContentView(R.layout.main);
int[] ids = {R.id.btn,R.id.btn2, R.id.btn3, R.id.btn4, R.id.btn5, R.id.btn6, R.id.btn7, R.id.btn8, R.id.btn9, R.id.btn10,
R.id.btn11, R.id.btn12, R.id.btn13, R.id.btn14, R.id.btn15, R.id.btn16 };
for (int i : ids) {
b = (Button) findViewById(i);
b.setOnClickListener(this);
}}
//outside of onCreate()
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn:
if (mp != null && mp.isPlaying()) mp.stop();
mp = MediaPlayer.create(zoo.this, R.raw.gata);
mp.start();
break;
this is the code and i use case for every btn.When the app forces down, the logCat is finding a NullPointerException in the mp.start(); of the button that forces the app down..please help!
EDIT in from comment below:
case R.id.btn:
if (mp != null && mp.isPlaying()) mp.stop();
mp.reset();
try {
mp.setDataSource("zoo.this,R.raw.gata");
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
mp.start();
break;
I think the point is that a MediaPlayer is a pretty heavy weight resource and you should not create too many of them. Also, as soon as you are done with it, call it's release() method. Anon's point's are both valid: you should try to reuse your media play instead of creating a new one and you should become very familiar with the MediaPlayer documentation. For instance from the MediaPlayer documentation:
Resource may include singleton
resources such as hardware
acceleration components and failure to
call release() may cause subsequent
instances of MediaPlayer objects to
fallback to software implementations
or fail altogether.
The hypothesis is that you are allocating lots of MediaPlayer objects and/or not releasing them fast enough. However, without more code it's impossible to be certain.

Categories

Resources