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

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();
}

Related

MediaController BACK button not work

I have a music app with MediaPayer and MediaController and when music play and i hit back button can't let the activity exit.
I found from source code that MediaController capture the KeyEvent.KEYCODE_BACK in MediaController#dispatchKeyEvent(). so I override the method by adding following code:
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return false;
}
return super.dispatchKeyEvent(event);
But it still no luck.
You can also override hide() method to show mediaController for every time like this:
mediaController = new MediaController(this){
#Override
public void hide() {
//do Nothing
}
//Handle BACK button
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
super.hide();//Hide mediaController
finish();//Close this activity
return true;//If press Back button, finish here
}
//If not Back button, other button (volume) work as usual.
return super.dispatchKeyEvent(event);
}
};
You need to release the MediaPlayer before you can execute finish() or onBackPressed(), this worked for me:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
MediaController mediaController = new MediaController(MyActivity.this){
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
mp.release();
super.hide();//Hide mediaController
finish();//Close this activity
return true;//If press Back button, finish here
}
//If not Back button, other button (volume) work as usual.
return super.dispatchKeyEvent(event);
}
};
videoView.setMediaController(mediaController);
videoView.start();
}
});
I came across this problem too. The solution to my problem was none of them above, was setting MediaController after VideoView prepared. See the code:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
videoView.setMediaController(mediaController);
}
});

Adding additional methods to MediaController buttons

I have a VideoView which plays a video and I call
videoPlayer.setMediaController(new MediaController(this));
to show the media controller buttons (play, pause, forward, backward).
The question is how am I able to add additional methods when I click the play or pause button of the MediaController?
Here's my class:
public class VideoPlayer extends Activity implements OnCompletionListener {
private String filename;
private VideoView videoPlayer;
private MediaPlayer mediaplayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.video_player);
System.gc();
Intent i = getIntent();
Bundle extras = i.getExtras();
filename = extras.getString("video_url");
System.out.println(filename);
videoPlayer = (VideoView) findViewById(R.id.videoPlayer);
videoPlayer.setOnCompletionListener(this);
videoPlayer.setKeepScreenOn(true);
videoPlayer.setVideoPath(filename);
videoPlayer.setMediaController(new MediaController(this));
videoPlayer.requestFocus();
videoPlayer.start();
mediaplayer = new MediaPlayer();
mediaplayer = MediaPlayer.create(
this,
Uri.parse("android.resource://" + getPackageName() + "/"
+ R.raw.alo));
mediaplayer.start();
}
/** This callback will be invoked when the file is finished playing */
#Override
public void onCompletion(MediaPlayer mp) {
// Statements to be executed when the video finishes.
this.finish();
}
/** Use screen touches to toggle the video between playing and paused. */
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (videoPlayer.isPlaying()) {
videoPlayer.pause();
mediaplayer.pause();
} else {
videoPlayer.start();
mediaplayer.start();
}
return true;
} else {
return false;
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
I'm not sure what you are trying to achieve.
You could extend a class with MediaController and implement some methods of your own. Basic OO principles.
private class MyMediaController extends MediaController {
#Override
public boolean onTouchEvent(MotionEvent event) {
// Your logic here
return super.onTouchEvent(event);
}
}

Make MediaController show without hide

I try to use MediaController to play music.
I want the MediaController appear until the "back" button is pressed.
Now I have try below code:
MediaController mediaController = new MediaController(this){
#Override
public void setMediaPlayer(MediaPlayerControl player) {
super.setMediaPlayer(player);
this.show();
}
#Override
public void show(int timeout) {
super.show(0);
}
//instead of press twice with press once "back" button to back
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
Activity a = (Activity)getContext();
a.finish();
}
return true;
}
};
But it still one trouble while the MediaController visible.
When the MediaController appear touch the screen, the MediaController will hide.
I also already try below code:
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("screen","touch");
return true;
}
But it did not work.
The string did not show in Logcat.
Anyone has idea to do it?
Override this method also inside media controller
#Override
public void hide() {
// TODO Auto-generated method stub
super.show();
}
If you want to keep the hide() method but not have the controller disappearing every time a control is used :
this.mediaController = new MediaController(this){
#Override
public void show(int timeout) {
super.show(0);
}
};

Help/Confused with MediaPlayer for 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);
}

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