Android VideoView (PhoneWindowLeaked Error) - android

I have a VideoView in my Activity with some TextView's and EditText below it. The Video in VideoView is loaded from server. I have to always show the Media Controls of VideoView. I have overriden the hide() in MediaController. In OnPrepared(), after start() I am setting the VideoView to show(). It is showing the controls which is what I wanted. I have written code to finish my activity when device back button is pressed. Now my issue is when I press phone's back button the activity doesn't finish. When I move to some other activity, it shows PhoneWindowLeaked exception in console. I have no clue about this. I could not find anything in google or even in this site. Please help me to solve this.
Sample code snippet is below :
VideoView mVideoView=(VideoView)findViewById(R.id.videoView);
mVideoView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mVideoView.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mVideoView.setVisibility(View.INVISIBLE);
}
});
mVideoView.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return true;
}
});
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK||keyCode == KeyEvent.KEYCODE_HOME) {
if(mVideoView.isPlaying()){
mVideoView.stopPlayback();
mVideoView.suspend();
}
finish();
return false;
}
return super.onKeyDown(keyCode, event);
}
mediaController = new MediaController(SampleActivity.this, true){
public void hide() {};
};
mediaController.setMediaPlayer(mVideoView);
mediaController.setAnchorView(mVideoView);
mediaController.requestFocus();
mVideoView.setMediaController(mediaController);
Uri video = Uri.parse(getResources().getString(R.string.img_path) + csPath);
mVideoView.setVideoURI(video);
mVideoView.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
mediaController.show(900000000);
}
});
#Override
protected void onPause() {
mediaController.hide();
mVideoView.stopPlayback();
mVideoView.suspend();
super.onPause();
}
#Override
protected void onStop() {
super.onStop();
mediaController.hide();
}
Thanks

Related

How to raise a toast when a seekbar is used in a videoview?

I am using video view to play files I need to raise a toast when the seekbar is clicked or used to seek video showing the current video duration. Any help?
MediaController mediaController = new MediaController(this.context);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
try {
videoView.setVideoURI(Uri.parse(url));
}
catch (Exception e){
Log.i("Error","In making connection");
}
videoView.requestFocus();
try{
videoView.setOnPreparedListener(new android.media.MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(android.media.MediaPlayer mediaPlayer) {
textViewPlayback.setVisibility(View.INVISIBLE);
Log.i("Inside","On prepare");
progressBar.setVisibility(View.INVISIBLE);
videoView.start();
videoView.seekTo(getSeekTime()*1000);
textViewPlayback.postDelayed(onEverySecond,10);
}
});
}
catch (Exception e){
Toast.makeText(this.context,"can not play this file",Toast.LENGTH_SHORT).show();
}
videoView.setOnErrorListener(new android.media.MediaPlayer.OnErrorListener() {
#Override
public boolean onError(android.media.MediaPlayer mediaPlayer, int i, int i1) {
Log.i("Error in playing","error");
return false;
}
});
videoView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Toast.makeText(getContext(),textViewPlayback.getText(),Toast.LENGTH_SHORT).show();
return false;
}
});
}
I am using video-view player to play and control media. I need to know is there any way that I can find out when the seekbar is touched in the video view controls.
You can use like this -
Add seekbar below your video view.
seekBar = (SeekBar) findViewById(R.id.seek_bar);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
seekBar.setProgress(0);
seekBar.setMax(recVideo.getDuration());
}
});
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Show toast here
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

Video does not resume in VideoView

Many posts are there for this issue.But the solutions are available for when the activity gets paused. I tried all it doesn't work. My problem is little bit different
I have a videoview and when the user clicks the videoview ,video will be paused and if he clicks again it should be resumed.
My code snippet in ontouchlistener is,
videopath = getIntent().getStringExtra("path");
imageView = ((VideoView) findViewById(R.id.imageView));
imageView.setVideoPath(videopath);
imageView.start();
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP)
if (layout.getVisibility()==View.VISIBLE) {
imageView.seekTo(stopPosition);
imageView.resume();
layout.animate().translationY(-layout.getHeight()).setDuration(500);
layout.setVisibility(View.GONE);
hideSystemUI();
} else {
imageView.pause();
stopPosition=imageView.getCurrentPosition();
showSystemUI();
layout.setVisibility(View.VISIBLE);
layout.animate().translationYBy(layout.getHeight());
}
return true;
}
});
I got this solution from this link . It doesn't work and simply using resume(); is also not working.
This happens because your device looses the time you've stored. You can use MediaPlayer instance, Here how you can use,
VideoView videoView;
MediaPlayer mp;
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
this.mp = mp;
}
});
public void pause(){
//NOT videoview.pause();
if (mp != null){
mp.pause();
}
}
public void resume(){
//NOT videoview.resume();
if (mp != null){
mp.start();
}
}
//This function will be implemented under onClick method
if (!videoView.isPlaying()) {
resume();
layout.setVisibility(View.GONE);
hideSystemUI();//hiding navigationbar
}
else {//initially layout visibility is GONE
pause();
stopPosition=videoView.getCurrentPosition();
showSystemUI();
layout.setVisibility(View.VISIBLE);
layout.animate().translationYBy(layout.getHeight());
}

Hide and Show Toolbar on MediaController show() and hide()

I'm using a MediaController to control video play back for my VideoView. I've overriden VideoView.setOnPreparedListener so that the ActionBar/Toolbar is hidden (hide()) after the video first finishes buffering. And I'd like the toolbar to comeback when the MediaController does. I've tried overriding the MediaController show() and hide() methods, like so:
mVideoView.start();
// Media Controller
mMediaController = new MediaController(this){
#Override
public void show() {
getSupportActionBar().show();
}
#Override
public void hide() {
getSupportActionBar().hide();
}
};
mMediaController.setAnchorView(mVideoView);
mVideoView.setMediaController(mMediaController);
// Hide toolbar once video starts
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// Hide support bar
getSupportActionBar().hide();
}
});
This works, except the playback controls stop showing up! And of course, calling a recursive mMediaController.show() within the overridden method doesn't work... Can I have my cake an eat it too?
Edit
So I've also, unsucessfully tried taking advantage of the VideoView.setOnTouchListener and VideoView.setOnCompletetionListener:
mVideoView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
getSupportActionBar().show();
return false;
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
getSupportActionBar().hide();
}
});
It does show, but it won't hide again, perhaps I misinterpret OnCompletetionListener?
Edit 2
From Amir's suggestion, I override the onTouch for VideoView, not perfect, but it's on like the right track:
mMediaController = new MediaController(this);
mVideoView = (VideoView) findViewById(R.id.media_player);
mVideoView.setOnTouchListener(new View.OnTouchListener() {
boolean flag;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(flag) {
mMediaController.hide();
getSupportActionBar().hide();
} else {
mMediaController.show();
getSupportActionBar().show();
}
flag = !flag;
return true;
}
return false;
}
});
This mostly works, it toggles the Toolbar and so sometimes the Toolbar will appear without the MediaController, and each time I toggle it, the MediaController does it's regular 'appear for a few seconds and then disappear.' In any case, it is a working solution.
Your original code seems to work if you add calls to the corresponding super methods.
mediaController = new MediaController(this){
#Override
public void show() {
super.show();
getSupportActionBar().show();
Toast.makeText(activity_media_player.this, "SHOW TOOLBAR", Toast.LENGTH_SHORT).show();
}
#Override
public void hide() {
super.hide();
getSupportActionBar().hide();
Toast.makeText(activity_media_player.this, "HIDE TOOLBAR", Toast.LENGTH_SHORT).show();
}
};
You should change your OnTouchListener a bit. I do following in my project and works fine:
final MediaController mediaController = new MediaController(this);
VideoView videoView = (VideoView) findViewById(R.id.videoView);
videoView.setOnTouchListener(new View.OnTouchListener() {
boolean flag = true;
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (flag) {
mediaController.hide();
hideToolbar();
}
else {
mediaController.show(0);
showToolbar();
}
flag = !flag;
return true;
}
return false;
}
});
videoView.setMediaController(mediaController);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
}
});
videoView.setVideoURI(Uri.parse("http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"));
And hideToolbar() with some traslate animation:
toolbar.animate().translationY(-toolbar.getBottom()).setInterpolator(new AccelerateInterpolator()).start();
showToolbar():
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start();
Also if you need to HideStatusBar call setUiFlag() with true:
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void setUiFlags(boolean fullscreen) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
View decorView = getWindow().getDecorView();
if (decorView != null) {
decorView.setSystemUiVisibility(fullscreen ? getFullscreenUiFlags() : View.SYSTEM_UI_FLAG_VISIBLE);
}
}
}
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private int getFullscreenUiFlags() {
int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN;
}
return flags;
}

How to set Looping conditions for VideoView in Android

I want to set looping conditions and for the VideoView. This is what I am trying to achieve.
Video Starts and finishes if Edit Text is not selected.
If Video Start and EditText is selected then Video is set to looping.
If the user types into the EditText and presses button submit then looping set to false and the activity closes after video completes.
If EditText loses selection the video activity finishes on complete.
Here is the code but it's not working for me
mVideoView.setVideoPath(phone);
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
#Override
public void onPrepared(final MediaPlayer mp) {
mVideoView.start();
if (mVideoView.isPlaying()) {
mp.setLooping(false);
}
}
}
);
CommentBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.setLooping(true);
}
});
}
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp1) {
finish();
}
}
);
Problem is you have not called mediaplayer.start() after you set loop in onCompletionListener().
I executed the below code and it works fine here
Solution:
Create public bundle type of variable
b=new Bundle();
b.putBoolean("repeat", false);
v.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.ak));
v.requestFocus();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (txt.getText().toString().length() > 0) {
b.putBoolean("repeat", false);
}
}
});
txt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean has) {
if (has) {
b.putBoolean("repeat", true);
}
}
});
v.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
if (b.getBoolean("repeat") == true) {
mediaPlayer.setLooping(true);
mediaPlayer.start();
Toast.makeText(getApplicationContext(),String.valueOf(b.getBoolean("repeat")),Toast.LENGTH_LONG).show();
} else {
mediaPlayer.setLooping(false);
mediaPlayer.stop();
Toast.makeText(getApplicationContext(),String.valueOf(b.getBoolean("repeat")),Toast.LENGTH_LONG).show();
}
}
});
v.start();

MediaController always show on Android

I am using mediacontroller in my app, but it shows only for 3 seconds. I have searched a lot, but in every document I see only the show function, set time out, but it has no effect. How can I always show mediacontroller?
I have tested show(0), but it had no effect.
You can extend the MediaController class and programmatically set an instance of it to a VideoView class:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.MediaController;
public class MyMediaController extends MediaController {
public MyMediaController(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyMediaController(Context context, boolean useFastForward) {
super(context, useFastForward);
}
public MyMediaController(Context context) {
super(context);
}
#Override
public void show(int timeout) {
super.show(0);
}
}
Here's the usage:
VideoView myVideoView = (VideoView) findViewById(R.id.my_video_view);
MediaController mc = new MyMediaController(myVideoView.getContext());
mc.setMediaPlayer(myVideoView);
myVideoView.setMediaController(mc);
You can create anonymous class inline and override certain methods. You need to override the hide method and do nothing in there. You also need to override the dispatchKeyEvent method to check for back key press and call the super.hide(). Otherwise on back press the controller wont hide and the activity cannot be closed.
mediaController = new MediaController(this){
#Override
public void hide() {
// TODO Auto-generated method stub
//do nothing
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mediaPlayer != null) {
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
super.hide();
Activity a = (Activity)getContext();
a.finish();
}
return true;
}
};
You can also create an anonymous class inline and override the hide method there instead of having to create a whole new class for it:
mediaController = new MediaController(this) {
#Override
public void hide() {
//Do not hide.
}
};
Try the show method in this way:
new media controller().show(50000);
And also check http://developer.android.com/reference/android/widget/MediaController.html#show().
SudeepSR: Please make a note of that, if you called show(0), it will show the Media Controller until hide() is called.
After trying all that I could, the following code worked for me!
mVideoView = (VideoView) findViewById(R.id.video);
mMediaController = new MediaController(this) {
//for not hiding
#Override
public void hide() {}
//for 'back' key action
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
Activity a = (Activity)getContext();
a.finish();
}
return true;
}
};
mMediaController.setAnchorView(mVideoView);
mMediaController.setMediaPlayer(mVideoView);
mVideoView.setMediaController(mMediaController);
mMediaController.requestFocus();
//only this showed the controller for me!!
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
mMediaController.show(900000000);
}
});
//finish after playing
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
finish();
}
});
What you need to do is, overrride the hide method in the custom controller and do nothing.
public class MyMediaController extends MediaController {
..
#Override
public void hide() {
// Do nothing here in order to always show
}
...
}
PS: You still need to click on the video to show the media controller.
This may be an old thread, but still unanswered, try this :
final MediaController mediaController = new MediaController(this);
mediaController.setAlwaysDrawnWithCacheEnabled(true);
mediaController.setAnchorView(vView);
mediaController.requestFocus();
vView.setOnPreparedListener( new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaController.show( 0 );
}
});
vView.setVideoPath(Preview_Path);
vView.setMediaController(mediaController);
vView.start();
theres a comment inside the MediaController Class "show" method
**Use 0 to show
* the controller until hide() is called**
so using 900000 or larger value wont help.
hope it helps you.
cheers.
Try this:
videoView.setOnCompletionListener(onVideoCompleted);
videoView.setOnPreparedListener(onVideoPrepared);
mc.setAnchorView(videoView);
mc.setMediaPlayer(videoView);
MediaController mc = new MediaController(this);
videoView.setMediaController(mc);
MediaPlayer.OnPreparedListener onVideoPrepared = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mc.show(0);
}
};
MediaPlayer.OnCompletionListener onVideoCompleted = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mc.hide();
}
};
I wanted to fade the controller for videos and always show it for audio. This worked
mController = new MediaController(this) {
#Override
public void hide() {
if (mType != TYPE_AUDIO) super.hide();
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
mController.hide();
Activity a = (Activity)getContext();
a.finish();
return true;
}
return false;
}
};
In MediaPlayer.onPrepared I added:
if (mType == TYPE_AUDIO) mController.show(0);
This causes the controller to show at the start of audio playback, but not video playback.
The other phone control buttons continue to work as normal.
Easy! Set visibility "GONE" in event hide and set visibility "VISIBLE" in show!
MediaController mc= new MediaController(zoom.this){
#Override
public void setMediaPlayer(MediaPlayerControl player) {
super.setMediaPlayer(player);
this.show(4000);
}
#Override
public void show(int timeout) {
super.show(timeout);
this.setVisibility(View.VISIBLE);
}
//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;
}
#Override
public void hide() {
// TODO Auto-generated method stub
super.hide();
this.setVisibility(View.GONE);
//super.show(3000);
}
};

Categories

Resources