mlw
mlw

Reputation: 375

MediaController 3 Second Issue

I am trying to use a MediaController and alter it so that it does not disappear after 3 seconds. I have found this code in a related question and I am using it:

mediaController = new MediaController(this) {   
    @Override
    public void hide()
    {
        mediaController.show();
    }
};

This code works, but when the activity stops (from using back button), I get log errors about a leaked window from a view added in the code below at the show(0) statement:

public void onPrepared(MediaPlayer mediaPlayer) {

    mediaController.setMediaPlayer(this);
    mediaController.setAnchorView(findViewById(R.id.audio_control));

    handler.post(new Runnable() {
      public void run() {
        mediaController.setEnabled(true);
        mediaController.show(0);
      }
    });
}

It seems to me that overriding the hide method by simply calling the show method means the hide method is not doing what is needed when finishing the activity. I must be overriding other necessary functionality, like actually hiding the controller!

I want to hide the controller when necessary (such as when finishing with it), but not in the case of when it is simply being hidden after 3 seconds (and the activity is not being finished).

Or maybe I should let the controller disappear after 3 seconds all the time but I am not sure I understand why it is implemented this way. It seems better to just keep it there all the time to me.

Upvotes: 1

Views: 955

Answers (1)

Kirby
Kirby

Reputation: 86

It's a bug in the MediaController:

private View.OnClickListener mPauseListener = new View.OnClickListener() {
    public void More ...onClick(View v) {
        doPauseResume();
        show(sDefaultTimeout);
    }
};

There are two ways to solve this.

A) Override the hide() method:

class MyMediaController extends MediaController {
    @Override
    public void hide() {
        // Nope, do not hide. Call hideActually() to actually hide. 
    }

    public void hideActually() {
        super.hide();
    }
}

B) Override the show() methods:

class MyMediaController extends MediaController {
    public int mTimeout = 0;

    @Override
    public void show() {
        show(mTimeout);
    }

    @Override
    public void show(int timeout) {
        super.show(mTimeout);
    }
}

Overriding the hide() method gives you the full control over hiding the MediaController, but you have to ensure calling hideActually() before the Activity is destroyed, else you'll get these log errors about a leaked window.

Overriding the show() methods gives you the chance to set a timeout after all. In this case there are some events on which the MediaController will hide without calling the hide() method explicitly, i.e. when the user presses the back button.

Personally I'd prefer using a mix of both implementations:

class MyMediaController extends MediaController {
    public int mTimeout = 0;

    @Override
    public void show() {
        show(mTimeout);
    }

    @Override
    public void show(int timeout) {
        super.show(mTimeout);
    }

    @Override
    public void hide() {
        // Do not hide until a timeout is set 
        if (mTimeout > 0) super.hide();
    }

    public void hideActually() {
        super.hide();
    }
}

In this case you have full control over showing and hiding the MediaController when mTimeout = 0, but you get the "normal" behaviour of the MediaController when you actually set a timeout.

Upvotes: 1

Related Questions