Est-il possible de suspendre n'importe quelle APP vidéo (mediaplayer) dans Android lorsque vous déroulez le panneau de notification?

11

Supposons que j'ai le code source AOSP, comment puis-je mettre en pause l'APP au premier plan lorsque je descends le panneau de notification? J'ai cherché sur Google et trouvé qu'une APP peut écouter l'événement onWindowFocusChangeet prendre des mesures de manière proactive, mais comment puis-je suspendre N'IMPORTE QUELLE APP en abaissant le panneau de notification, sans modifier respectivement chaque APP (ce qui n'est pas pratique)?

Existe-t-il un moyen d'appeler la onPausefonction d'une application de premier plan à partir du processus SystemUI?

Zhangxaochen
la source
réponse ajoutée à toutes vos questions voir ceci - stackoverflow.com/a/59589825/9640177
mayank1513
La clé lance une activité transparente lorsque la notification est abaissée. Cela appellera la méthode onPause de l'activité en cours. alors que la demande de focus entraînera une pause dans la lecture des médias
mayank1513

Réponses:

10

Vous pouvez utiliser la méthode ci-dessous pour détecter l'attraction du panneau de notification,

Dans votre fichier manifeste

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

Dans votre activité, remplacez le onWindowFocusChanged()et écrivez le code ci-dessous.

Cela utilise l'autorisation

@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();
        }
    }
}

Ensuite, dans votre demande d'application pour le focus audio, reportez-vous au lien ci-dessous

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

Cela suspendra l'accès audio pour toutes les autres applications.

Akash Dubey
la source
1
@zhangxaochen bounty expire dans 5 heures, vous l'avez déjà perdu et, s'il expire, il est perdu !!
Akash Dubey
3

La solution comporte deux parties

  1. détection de la traction du panneau de notification
  2. suspendre toute application de lecture multimédia

Pour détecter la traction du panneau de notification, vous pouvez utiliser la méthode suggérée par Akash ou le même code ici par Lalith.

Dans votre fichier manifeste

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

Dans votre activité, remplacez onWindowFocusChanged () et écrivez le code ci-dessous.

@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();
        }
    }
}

Pour la deuxième partie, tous les lecteurs multimédias bien conçus implémentent des écouteurs de changement de focus audio. Ainsi, pour mettre en pause toutes les applications du lecteur multimédia, vous pouvez demander un focus audio temporaire ou complet selon que vous souhaitez laisser les applications jouer à nouveau dès que le panneau de notification est réduit.

Utiliser suivant

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);

N'oubliez pas d'implémenter 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
    }
};

Existe-t-il un moyen d'appeler la fonction onPause d'une application de premier plan à partir du processus SystemUI?

Pour autant que j'ai fait des recherches sur le système, le processus de l'interface utilisateur n'est pas accessible. Cependant, vous pouvez lancer une activité avec un thème transparent .

Dans votre manifeste

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

voyez cela et j'ai aussi personnellement testé la création d'une activité transparente.

Cela signifie que l'activité en haut maintenant est votre activité transparente et la méthode onPause de l'autre activité sera naturellement appelée. Une fois le panneau de notification réduit, vous pouvez détruire cette activité. Et pour être sûr, vous pouvez également définir l'écouteur onTouch en créant une vue vide qui sent l'écran qui devrait détruire l'activité onTouch.

mayank1513
la source
3

En supposant que l' appareil Android utilise le MediaPlayer par défaut , selon ce diagramme d'état , vous pouvez utiliser le natif pauseet l' stopétat.

Si vous ne souhaitez pas arrêter le son, vous pouvez probablement changer le volume sonore à l'aide d'une fonction VolumeAutomation ?

A STEFANI
la source