Czy możliwe jest wstrzymanie dowolnej aplikacji wideo (mediaplayer) w systemie Android po rozwinięciu panelu powiadomień?

11

Załóżmy, że mam kod źródłowy AOSP. Jak mogę zatrzymać aplikację na pierwszym planie podczas opuszczania panelu powiadomień? Poszukałem go i stwierdziłem, że aplikacja może nasłuchiwać zdarzenia onWindowFocusChangei podejmować pewne działania proaktywnie, ale jak mogę zatrzymać DOWOLNĄ APLIKACJĘ podczas opuszczania panelu powiadomień bez modyfikacji odpowiednio każdej aplikacji (co jest niepraktyczne)?

Czy istnieje sposób, że mogę wywołać onPausefunkcję dowolnej aplikacji pierwszego planu z procesu SystemUI?

zhangxaochen
źródło
dodana odpowiedź na wszystkie pytania zobacz to - stackoverflow.com/a/59589825/9640177
mayank1513
Klucz uruchamia przezroczyste działanie po usunięciu powiadomienia. To wywoła metodę bieżącej aktywności onPause. podczas gdy żądanie skupienia spowoduje wstrzymanie odtwarzania multimediów
mayank1513

Odpowiedzi:

10

Możesz użyć poniższej metody wykrywania ściągnięcia panelu powiadomień,

W twoim pliku manifestu

 <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />

W swojej działalności zastąp onWindowFocusChanged()i napisz poniższy kod.

To używa pozwolenia

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
    try
    {
        if(!hasFocus)
        {
            Object service  = getSystemService("statusbar");
            Class<?> statusbarManager = Class.forName("android.app.StatusBarManager");
            Method collapse = statusbarManager.getMethod("collapse");
            collapse .setAccessible(true);
            collapse .invoke(service);
        }
    }
    catch(Exception ex)
    {
        if(!hasFocus)
        {
            try {
                Object service  = getSystemService("statusbar");
                Class<?> statusbarManager = Class.forName("android.app.StatusBarManager");
                Method collapse = statusbarManager.getMethod("collapse");
                collapse .setAccessible(true);
                collapse .invoke(service);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();                
            }
            ex.printStackTrace();
        }
    }
}

Następnie w prośbie aplikacji o fokus audio zapoznaj się z linkiem poniżej

https://developer.android.com/guide/topics/media-apps/audio-focus#java

Spowoduje to wstrzymanie dostępu audio dla wszystkich innych aplikacji.

Akash Dubey
źródło
1
@zhangxaochen bounty wygasa za 5 godzin, już go straciłeś, a jeśli wygasł, został zmarnowany !!
Akash Dubey,
3

Rozwiązanie składa się z dwóch części

  1. wykrywanie ściągnięcia panelu powiadomień
  2. wstrzymywanie dowolnej aplikacji do odtwarzania multimediów

Aby wykryć ściąganie panelu powiadomień, możesz zastosować metodę sugerowaną przez Akash lub ten sam kod tutaj przez Lalith.

W twoim pliku manifestu

<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />

W swojej działalności zastąp metodę onWindowFocusChanged () i napisz poniższy kod.

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
    try
    {
        if(!hasFocus)
        {
            Object service  = getSystemService("statusbar");
            Class<?> statusbarManager = Class.forName("android.app.StatusBarManager");
            Method collapse = statusbarManager.getMethod("collapse");
            collapse .setAccessible(true);
            collapse .invoke(service);
        }
    }
    catch(Exception ex)
    {
        if(!hasFocus)
        {
            try {
                Object service  = getSystemService("statusbar");
                Class<?> statusbarManager = Class.forName("android.app.StatusBarManager");
                Method collapse = statusbarManager.getMethod("collapse");
                collapse .setAccessible(true);
                collapse .invoke(service);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();                
            }
            ex.printStackTrace();
        }
    }
}

W drugiej części wszystkie dobrze zaprojektowane odtwarzacze multimedialne wykorzystują Audio Focus Change Listeners. Dlatego, aby wstrzymać wszystkie aplikacje odtwarzacza multimediów, możesz poprosić o tymczasowe lub pełne skupienie dźwięku w zależności od tego, czy chcesz zezwolić aplikacjom na odtwarzanie, gdy tylko panel powiadomień zostanie zwinięty.

Użyj następujących

AudioManager audioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
playbackAttributes = new AudioAttributes.Builder()
    .setUsage(AudioAttributes.USAGE_GAME)
    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
    .build();
focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
    // replace AUDIOFOCUS_GAIN with AUDIOFOCUS_GAIN_TRANSIENT if you want to pause and again resume when notification panel collapsed
    .setAudioAttributes(playbackAttributes)
    .setAcceptsDelayedFocusGain(true)
    .setOnAudioFocusChangeListener(afChangeListener, handler)
    .build();
// to requestAudioFocus and pause other media apps
audioManager.requestAudioFocus(focusRequest);

// to resume again in case you requested AUDIOFOCUS_GAIN_TRANSIENT
audioManager.abandonAudioFocus(afChangeListener);

Nie zapomnij wdrożyć AudioFocusChangeListener

AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() {
    @Override
    public void onAudioFocusChange(int focusChange) {
        // leave this empty if you don't need to handle audio focus for your app
    }
};

Czy istnieje sposób, aby wywołać funkcję onPause dowolnej aplikacji na pierwszym planie z procesu SystemUI?

O ile badałem proces interfejsu użytkownika systemu nie jest dostępny. Możesz jednak uruchomić działanie z przezroczystym motywem .

W twoim manifeście

<activity android:name=".your.activity" android:theme="@android:style/Theme.Translucent.NoTitleBar" />

zobacz to i osobiście przetestowałem, tworząc przejrzystą aktywność.

Oznacza to, że aktywność na górze jest teraz twoją przezroczystą aktywnością, a metoda onPause innej aktywności zostanie naturalnie wywołana. Po zwinięciu panelu powiadomień możesz zniszczyć tę aktywność. Aby być bezpiecznym, możesz również ustawić odbiornik onTouch, tworząc pusty widok, który odczuwa ekran, który powinien zniszczyć aktywność onTouch.

mayank1513
źródło
3

Zakładając, że urządzenie z Androidem używa domyślnego MediaPlayera , zgodnie z tym diagramem stanu , możesz użyć rodzimego pausei stopstanu.

Jeśli nie chcesz tylko zatrzymać dźwięku, prawdopodobnie możesz zmienić głośność za pomocą VolumeAutomation ?

STEFANI
źródło