Не удается расширить android.widget.MediaController для переопределения setSystemUiVisibility

Я работаю над своим первым приложением для Android. Он предназначен для погружения и скрывает панель навигации на всех активах, обеспечивая при этом собственную внутреннюю навигацию через панель действий.

Я обязуюсь использовать представление 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.

У меня проблема в том, что каждая переменная этого класса является закрытой, как и большинство методов. Есть нулевые методы получения или установки для любой из частных переменных. Поэтому я не могу изменить взаимодействие метода 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 не распознается, так что это также помешает мне повторить этот класс.

Почему этот метод недоступен?

Если есть какой-то другой способ принудительно запретить окнам изменять свои параметры SystemUiVisibility или какой-либо другой способ расширить метод show без воспроизведения всего класса, это было бы предпочтительным!

Любое руководство будет оценено.

1 ответ

Я столкнулся с той же проблемой прямо сейчас.. Я хочу внести изменения в класс MediaController.

Я думал, что в классе была ошибка, потому что он не импортировал PhoneWindow, и что getInstance (context) вызывал ошибки, но теперь я вижу, что это способ защитить код.

Я нашел этот ответ на stackru:

Поскольку com.android.internal.telefony подпадает под внутренние (или скрытые) API-интерфейсы Android, вы не можете напрямую импортировать его. Но есть способы поработать с ними. Я бы посоветовал вам обойти это и это, чтобы получить представление о том, как работать с телефонией через рефлексию.

Это не о классе PhoneWindow, но я думаю, что было бы возможно сделать что-то подобное с этим классом. Я не пробовал это, но, может быть, вы можете?

Другие вопросы по тегам