La solución tiene dos partes.
- detección de extracción del panel de notificaciones
- pausar cualquier aplicación de reproducción de medios
Para detectar la extracción del panel de notificaciones, puede emplear el método sugerido por Akash o el mismo código aquí por Lalith.
En su archivo de manifiesto
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
En su actividad, anule onWindowFocusChanged () y escriba el siguiente código.
@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();
}
}
}
Para la segunda parte, todos los reproductores multimedia bien diseñados implementan oyentes de cambio de enfoque de audio. Por lo tanto, para pausar todas las aplicaciones del reproductor de medios, puede solicitar un enfoque de audio temporal o completo dependiendo de si desea permitir que las aplicaciones se reproduzcan nuevamente tan pronto como el panel de notificaciones esté colapsado.
Usar siguiente
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);
No olvides implementar 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
}
};
¿Hay alguna manera de llamar a la función onPause de cualquier aplicación en primer plano desde el proceso SystemUI?
Por lo que he investigado, el proceso ui del sistema no es accesible. Sin embargo, puede iniciar una actividad con un tema transparente .
En tu manifiesto
<activity android:name=".your.activity" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
veo esto y también he probado personalmente la creación de actividad transparente.
Esto significa que la actividad en la parte superior ahora es su actividad transparente y, naturalmente, se llamará al método onPause de la otra actividad. Una vez que el panel de notificaciones está colapsado, puede destruir esta actividad. Y para estar seguro, también puede configurar onTouch listener creando una vista vacía que sienta la pantalla que debería destruir la actividad en Touch.