Help/Confused with MediaPlayer for Android? - android

I been trying to program this soundboard for android but I'm stuck and confused on how to stop a sound from playing when I exit the program with the back key and also when clicking on another sound. I've looked all over the place and even on the android developer website an I'm still confused on what to do. If someone could please help me out i'll greatly appreciate it. My MediaPlayer code im going to post but if the actually soundboard code is needed i'll be happy to post that also.
package com.cs.finalfantasysoundboard;
import android.content.Context;
import android.media.MediaPlayer;
public class Music
{
public interface OnCompletionListener {
}
private static MediaPlayer mp = null;
/** Stop old song and start new one */
public static void play (Context context, int resource)
{
stop(context);
mp = MediaPlayer.create(context, resource);
mp.stop();
mp.start();
}
/** Stop the music */
public static void stop(Context context)
{
mp.reset();
mp.release();
mp = null;
}
}

you can implement some flags for sound being played or stopped etc. Here is how you can stop the sound on Back Key:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK /*&& event.getRepeatCount() == 0*/)
{
if(!isStopped)
{
stop();
}
//System.exit(0); //if you want to exit directly or this.finish(); etc
return true;
}
return super.onKeyDown(keyCode, event);
}

Related

Turn on/off Sound

I would like to turn the sound on and off by clicking on the button.
public void onClick(View v) {
buttonSound.setBackgroundResource(R.drawable.soundan);
CommonMethod.soundplayer.stop();
//buttonSound.setBackgroundResource(R.drawable.soundaus);
//CommonMethod.soundplayer.setVolume(0,0);
}
This is the CommonMethod
public class CommonMethod {
public static MediaPlayer soundplayer;
public static void Soundplayer(Context ctx,int raw_id)
{
soundplayer = MediaPlayer.create(ctx,raw_id);
soundplayer.setLooping(true);
soundplayer.setVolume(100, 100);
}
}
It stops the sound by clicking but it doesn't turn it on again
I got this Code too, but its the same problem
public void onClick(View v) {
// TODO Auto-generated method stub
counter++;
if (counter % 2 == 0) {
buttonSound.setBackgroundResource(R.drawable.soundan);
CommonMethod.soundplayer.setVolume(100,100);
}
else
{
buttonSound.setBackgroundResource(R.drawable.soundaus);
CommonMethod.soundplayer.setVolume(0,0);
}
}
Please see this piece of documentation
There are some useful ballots like:
A MediaPlayer object must first enter the Prepared state before
playback can be started.
or
Once in the Stopped state, playback cannot be started until prepare()
or prepareAsync() are called to set the MediaPlayer object to the
Prepared state again.
You can pause it instead of stooping if you stop then you have prepaid it again then it will play rather then you can pause and play`` again from same position.
if(mPlayer.isPlaying()){
mPlayer.pause();
} else {
mPlayer.start();
}
understand the below diagram.

how to stop the playing sound from interface by main activity?

I am beginner at Android App I have new app which call html files from assets file one of the task on this app is when user selected check box input to value "on" the mp3 play and when user goout from app as press back button or press home button the sound stopped and close the app. I did my interface between html and main activity to call java methods at html. When I added my code to stop the sound it does not play . I tried to add this line of code in main activity oncreate method .
mp= MediaPlayer.create(mContext,R.raw.sound);
the sound stopped when press back or home or turnoff buttons . but the sound work when i open the app but this what i doesnot need i need this is when user select the checkbox . so how can i do it .
#Override
protected void onPause()
{
super.onPause();
if(mp.isPlaying())
mp.pause(); //stop the sound
}
#Override
protected void onResume()
{
super.onResume();
mp.start();
}
public class WebAppInterface {
Context mContext;
private MediaPlayer mp;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void playsound(String value ) {
if (value.equals("on")) {
mp= MediaPlayer.create(mContext,R.raw.sound);
mp.setLooping(true);
mp.start();
}
else
{ mp.stop();}
}
}
I am assuming the issue is that the sound plays regardless whether you have selected the checkbox or not. A way to fix this would be to confirm whether the checkbox is checked or not in the onResume() method, instead of just starting regardless.
public class WebAppInterface extends Ramadan {
Context mContext;
private MediaPlayer mp;
private static boolean checked = false;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void playsound(String value , MediaPlayer mp ) {
if (value.equals("on")) {
checked = true;
mp= MediaPlayer.create(mContext,R.raw.sound);
mp.setLooping(true);
mp.start();
}
else
{
checked = false;
mp.stop();
}
}
}
in your main class:
#Override
protected void onPause()
{
super.onPause();
if(mp.isPlaying())
mp.pause(); //stop the sound
}
#Override
protected void onResume()
{
super.onResume();
if(WebAppInterface.checked)
{
mp.start();
}
}

How can I stop media player in another activity?

I start mediaplayer like this:
if (mp != null) {
mp.stop();
mp.reset();
mp.release();
}
mp = MediaPlayer.create(this, R.raw.background);
mp.start();
How can I stop in another activity? It continues to play in another activity. How can I use onDestroy in another activity?
Use the Separate class like below in your project.
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
public class AudioPlay {
public static MediaPlayer mediaPlayer;
private static SoundPool soundPool;
public static boolean isplayingAudio=false;
public static void playAudio(Context c,int id){
mediaPlayer = MediaPlayer.create(c,id);
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
if(!mediaPlayer.isPlaying())
{
isplayingAudio=true;
mediaPlayer.start();
}
}
public static void stopAudio(){
isplayingAudio=false;
mediaPlayer.stop();
}
}
Playing the song
`AudioPlay.playAudio(mContext, R.raw.audiofile);` // play it from your preferred activity. and you can change raw file to your path also its depends upon your requirement.
then
stop the audio using this lines AudioPlay.stopAudio(); from any activity.
hope this helps.
In 1st activity override onPause
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mp.stop();
}
This is my Kotlin solution:
package com.programacionymas.myapp.services
import android.content.Context
import android.media.MediaPlayer
object AudioPlay {
var mediaPlayer: MediaPlayer? = null
var lastResource: Int? = null
fun playAudio(c: Context, id: Int, isLooping: Boolean = true) {
createMediaPlayer(c, id)
mediaPlayer?.let {
it.isLooping = isLooping
if (!it.isPlaying) {
it.start()
}
}
}
private fun createMediaPlayer(c: Context, id: Int) {
// in case it's already playing something
mediaPlayer?.stop()
mediaPlayer = MediaPlayer.create(c, id)
lastResource = id
}
// usually used inside the Activity's onResume method
fun continuePlaying(c: Context, specificResource: Int? = null) {
specificResource?.let {
if (lastResource != specificResource) {
createMediaPlayer(c, specificResource)
}
}
mediaPlayer?.let {
if (!it.isPlaying) {
it.start()
}
}
}
fun pauseAudio() {
mediaPlayer?.pause()
}
}
I started from itsrajesh4uguys's Java answer, and I applied these changes:
Remove the Boolean attribute, since it was not being used
Add an attribute to track the last loaded resource, this way I can continue playing it or replace with other resource
Call the stop function before creating a new instance, to avoid overlapping
Finally I use it this way:
In the onCreate method:
AudioPlay.playAudio(this, R.raw.background_music)
In the onResume method:
AudioPlay.continuePlaying(this, R.raw.background_music)
In my case I had to specify the resource, because some of my Activities start playing another music sounds.
you cannot call stop an activity but from the activity itself to
achive this you can send the media player in a service and bind to the service in the activities you want to access it
As you have started media player in first activity and wanted to stop in another activity, just call your second layout in first activity using layout inflater self instead of creating another activity.. and on second layout file just stop the media player by pressing a button
public class FirstAvtivity extends Activity
{
MediaPlayer mPlayer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_activity_layoutfile);
Button b=(Button)findViewById(R.id.button1);
//start the media player like how you were starting in your activity
// then after clicking button you will be navigated to new layout , there
// you can stop media player
mPlayer.start();
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateLayout();
}
});
}
private void newUpdateLayout() {
LayoutInflater inflater = LayoutInflater.from(this);
setContentView(inflater.inflate(R.layout.second_disapr_scr, null));
finalDismiss=(Button)findViewById(R.id.final_dismiss);
finalDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),"welcome to second
avtivity",Toast.LENGTH_SHORT).show();
mPlayer.stop();
finish();
}
});
}
}

Android - VideoView requires to press BACK twice, in order to exit

I have an activity with different video files displayed. When I click a video file, I'm taken to another activity, where a VideoView plays the video.
My issue is that when I want to exit this activity and return back to previous, I should click twice the back button, in order to return back. If I click only once, the video starts playing once again, and only at the second attempt I'm allowed to exit the screen.
Then I tried this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Log.d(Constants.LOG_TAG, "back pressed in videoplayer");
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
And, although I see in the logcat "back pressed in video player", the activity does not exit. I still should press twice the back button.
EDIT: This is the most relevant (I believe) source code. Note however, that the video is played from the internet, and I'm not using the Mediacontroller, instead I'm defining my own layout and link to videoview conrols.
public class VideoPlayer extends Activity implements OnClickListener, OnCompletionListener,
OnSeekBarChangeListener, OnPreparedListener, OnTouchListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_view);
// Gets the position of clicked video, from an ArrayList of video urls.
selectedVideo = getPosition();
// the play button
play = (ImageButton) findViewById(R.id.play);
play.setOnClickListener(this);
videoView = (VideoView) findViewById(R.id.videoView);
videoView.setOnCompletionListener(this);
videoView.setOnPreparedListener(this);
videoView.setOnTouchListener(this);
// the url to play
String path = videoUris.get(selectedVideo);
videoView.setVideoPath(getPath(path));
}
/**
* Play or Pause the current video file.
*
* If the video is paused, then invoking this method should start it. If the video is already playing, then the
* video should pause.
*/
private void play() {
if (!isVideoStarted) {
isVideoStarted = true;
videoView.start();
play.setImageResource(R.drawable.video_pause);
videoSeekBar.post(updateSeekBarRunnable);
} else if (isVideoStarted) {
isVideoStarted = false;
pause();
}
}
/**
* Start playing back a video file with the specified Uri.
*/
private void startPlayback() {
String path = videoUris.get(selectedVideo);
videoView.setVideoPath(getPath(path));
videoView.start();
}
/**
* Stops the currently playing video. (The SeekBar position is reset to beginning, 0.)
*/
private void stopPlayback() {
videoView.stopPlayback();
}
/**
* Pause the currently playing video. (The SeekBar remains in its position.)
*/
private void pause() {
videoView.pause();
#Override
public void onPrepared(MediaPlayer mp) {
play();
}
}
Code below work fine for me:
try
{
MediaController mc = new MediaController(YourActivity.this);
mc.setAnchorView(vd);
Uri uri = Uri.parse(YourURL);
vd.setMediaController(mc);
vd.setVideoURI(uri);
//vd.start();
}catch(Exception e)
{
Log.e("Error", e.getMessage());
e.printStackTrace();
}
vd.requestFocus();
vd.start();
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode == KeyEvent.KEYCODE_BACK)
{
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
Thank you for trying to help me.
It turned out that I was calling startActivity(intent); twice, and that is why I should press the back button twice.
Can you try overriding the onBackPressed instead of KeyEvent. Because your code seems to look correct.
Remove this,
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Log.d(Constants.LOG_TAG, "back pressed in videoplayer");
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
And add,
#Override
public void onBackPressed() {
finish();
}

Problem with back button in VideoView

I am having difficulty getting the back button to actually finish my activity when pressed. I am running a very simple videoview, using a progressdialog to show loading dialog and onpreparedlistener, etc etc. simple stuff. Anyways, currently when I press the back button, it will just cancel the progressdialog, and leave a black screen, and pressed again, the progressdialog restarts!!! and then when I click the back button again, it displays an alert dialog, "video cannot be played." very annoying. Thanks for your help.
public class VideoActivity extends Activity {
private VideoView mVideoView;
private static ProgressDialog progressdialog;
private String path;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoview);
progressdialog = ProgressDialog.show(this, "", " Video Loading...", true);
progressdialog.setCancelable(true);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVideoView.setMediaController(new MediaController(this));
Bundle b = this.getIntent().getExtras();
path = b.getString("path");
mVideoView.setVideoURI(Uri.parse(path));
mVideoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
progressdialog.dismiss();
mVideoView.requestFocus();
mVideoView.start();
}
});
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
super.finish();
}
}
You can simply write: (No need to create new class for MediaController)
mVideoView.setMediaController(new MediaController(this){
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)
((Activity) getContext()).finish();
return super.dispatchKeyEvent(event);
}
});
You'll want to create a custom MediaController class and override the dispatchKeyEvent function to capture the back KeyEvent and tell the activity to finish.
See Android back button and MediaController for more info.
public class CustomMediaController extends MediaController {
public CustomMediaController(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomMediaController(Context context, boolean useFastForward) {
super(context, useFastForward);
}
public CustomMediaController(Context context) {
super(context, true);
}
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
((Activity) getContext()).finish();
return super.dispatchKeyEvent(event);
}
}
From CommansWare
Based on the source code, this should work:
Extend MediaController (for the purposes of this answer, call it
RonnieMediaController)
Override dispatchKeyEvent() in RonnieMediaController
Before chaining to the superclass, check for KeyEvent.KEYCODE_BACK,
and if that is encountered, tell your activity to finish()
Use RonnieMediaController instead of MediaController with your
VideoView
Personally, I'd just leave it alone, as with this change your user
cannot make a RonnieMediaController disappear on demand.
Here is the link to the original post.
finish() doesn't kill your activity, it just signals to Android that it doesn't need to run the Activity anymore.
I remember solving this by putting "return" in proper places.
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
System.exit(0);
}
return false;
}

Categories

Resources