无法扩展android.widget.MediaController以覆盖setSystemUiVisibility

时间:2017-04-05 07:01:03

标签: java android android-gradle mediacontroller

我正在开发我的第一款Android应用。它设计为沉浸式,并将NavigationBar隐藏在所有活动上,同时通过ActionBar提供自己的内部导航。

我承诺使用此应用的默认MediaController视图。我正在使用android.widget.MediaController作为MediaController通过android.widget.VideoView进行全屏视频活动。我还使用了android.widget.MediaController的扩展程序,通过MediaController.MediaPlayerControl实现android.media.MediaPlayer非全屏音频活动。

在调查android.widget.MediaController来源后,它会在新窗口中将当前活动显示为FrameLayout。每当要显示MediaController时,它都会通过调用下面的mWindowManager.addView(mDecor, mDecorLayoutParams);将自己添加到窗口,其中包含一组特定的布局参数。

public void show(int timeout) {
    if (!mShowing && mAnchor != null) {
        setProgress();
        if (mPauseButton != null) {
            mPauseButton.requestFocus();
        }
        disableUnsupportedButtons();
        updateFloatingWindowLayout();
        mWindowManager.addView(mDecor, mDecorLayoutParams);
        mShowing = true;
    }
    updatePausePlay();

    // cause the progress bar to be updated even if mShowing
    // was already true.  This happens, for example, if we're
    // paused with the progress bar showing the user hits play.
    post(mShowProgress);

    if (timeout != 0 && !mAccessibilityManager.isTouchExplorationEnabled()) {
        removeCallbacks(mFadeOut);
        postDelayed(mFadeOut, timeout);
    }
}

此调用的结果是为此窗口重置SystemUiVisibility,并且应用程序退出沉浸式模式,显示NavigationBar。

我遇到的问题是这个类的每个变量都是私有的,就像大多数方法一样。任何私有变量都有零getter或setter。所以,我无法改变show方法与其变量的交互。

在扩展MediaController类时,我只能覆盖show方法以立即调用hideNavigation。但是,每次显示控制器时,NavigationBar仍会短暂出现在屏幕上!这不是我感到满意的解决方案。

// MediaController implementation
@Override
public void show(int timeout) {
    super.show(timeout);

    // hide navigation
    hideNavigation();
}

// hide navigation
public void hideNavigation() {

    // get root view
    View rootView = this.getRootView();

    // options
    final int options =
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_FULLSCREEN |
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
    ;

    // set visibility options
    rootView.setSystemUiVisibility(options);
}

所以,鉴于我无法正确扩展类,由于它的私有设计,我想完全用我自己的代替它,使用原始的大部分代码,只使用受保护的变量和方法而不是私人的。

这种方法的问题是我无法将import com.android.internal.policy.PhoneWindow;添加到我的Android Studio项目中。如何在Gradle构建中包含此包?

compile 'com.android.internal.policy:phonewindow:1.0'

我需要更改才能使其工作?或者,这是不可能的吗?

此外,我可以看到无法识别对getInstance(Context context) android.view.accessibility.AccessibilityManager方法的调用,因此也会阻止我复制此类。

为什么这种方法不可用?

如果有其他方法可以强制阻止Windows更改其SystemUiVisibility选项,或者某种其他方式来扩展show方法而不重现整个类,那么这将是更好的选择!

任何指导都将不胜感激。

1 个答案:

答案 0 :(得分:0)

我现在面临同样的问题..我想对MediaController类进行更改。

我虽然在类中有一个错误,因为它不会导入PhoneWindow,并且getInstance(context)会引发错误,但现在我发现这是一种保护代码的方法。

我在stackoverflow上找到了这个答案:

由于com.android.internal.telefony属于Android的内部(或隐藏)API,因此无法直接导入它。但是有办法与他们合作。我建议你通过thisthis来了解如何通过反思来处理电话。

这不是关于PhoneWindow类,但我认为可以用这个类做类似的事情。我没试过,但也许你可以吗?