116 votes

Comment vérifier si une activité est au premier plan ou en arrière-plan visible ?

J'ai un écran d'accueil sur une minuterie. Mon problème est qu'avant que je finish() mon activité, j'ai besoin de vérifier que l'activité suivante a démarré car une boîte de dialogue système s'affiche et je souhaite seulement finish() ; une fois que l'utilisateur a sélectionné une option dans la boîte de dialogue ?

Je sais qu'il y a beaucoup de questions sur la façon de voir si votre activité est au premier plan, mais je ne sais pas si cela permet aussi de placer des boîtes de dialogue au-dessus de l'activité.

Voici le problème, le rouge représente mon activité qui est en arrière-plan alors que le dialogue est au premier plan :

the red is my activity which is in the background while the dialogue is in the foreground

EDIT : J'ai essayé de ne pas utiliser finish() mais alors mon activité peut être reprise dans la pile d'applications, ce que j'essaie d'éviter.

198voto

C'est ce qui est recommandé comme droite solution :

La bonne solution (les crédits vont à Dan, CommonsWare et NeTeInStEiN) Suivez vous-même la visibilité de votre application en utilisant méthodes Activity.onPause, Activity.onResume. Stockez le statut de "visibilité dans une autre classe. Les bons choix sont votre propre implémentation de l l'application ou d'un service (il existe également quelques variantes de cette solution si vous souhaitez vérifier la visibilité de l'activité à partir du service).

Exemple Implémentez la classe d'application personnalisée (notez la méthode statique isActivityVisible()) :

public class MyApplication extends Application {

  public static boolean isActivityVisible() {
    return activityVisible;
  }  

  public static void activityResumed() {
    activityVisible = true;
  }

  public static void activityPaused() {
    activityVisible = false;
  }

  private static boolean activityVisible;
}

Enregistrez votre classe d'application dans AndroidManifest.xml :

<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

Ajoutez onPause et onResume à chaque Activité du projet (vous pouvez créer un ancêtre commun pour vos Activités si vous le souhaitez, mais si votre activité est déjà étendue à partir de MapActivity/ListActivity etc. vous devez toujours écrire ce qui suit à la main) :

@Override
protected void onResume() {
  super.onResume();
  MyApplication.activityResumed();
}

@Override
protected void onPause() {
  super.onPause();
  MyApplication.activityPaused();
}

Dans votre finish() vous voulez utiliser la méthode isActivityVisible() pour vérifier si l'activité est visible ou non. Vous pouvez également vérifier si l'utilisateur a sélectionné une option ou non. Continuez lorsque les deux conditions sont remplies.

La source mentionne également deux solutions erronées... évitez donc de le faire.

Source : stackoverflow

73voto

CodeRat Points 1718

Si on vise le niveau 14 de l'API ou plus, on peut utiliser Android.app.Application.ActivityLifecycleCallbacks

public class MyApplication extends Application implements ActivityLifecycleCallbacks {
    private static boolean isInterestingActivityVisible;

    @Override
    public void onCreate() {
        super.onCreate();

        // Register to be notified of activity state changes
        registerActivityLifecycleCallbacks(this);
        ....
    }

    public boolean isInterestingActivityVisible() {
        return isInterestingActivityVisible;
    }

    @Override
    public void onActivityResumed(Activity activity) {
        if (activity instanceof MyInterestingActivity) {
             isInterestingActivityVisible = true;
        }
    }

    @Override
    public void onActivityStopped(Activity activity) {
        if (activity instanceof MyInterestingActivity) {
             isInterestingActivityVisible = false;
        }
    }

    // Other state change callback stubs
    ....
}

52voto

Alex Misulya Points 45

UPD : mis à jour pour indiquer Lifecycle.State.RESUMED . Merci à @htafoya pour ça.

En 2019, avec l'aide de la nouvelle bibliothèque de soutien 28+ ou AndroidX vous pouvez simplement utiliser :

val isActivityInForeground = activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)

Vous pouvez en savoir plus dans la documentation pour comprendre ce qui s'est passé sous le capot.

14voto

Burak Day Points 532

[Activity::hasWindowFocus()](https://developer.android.com/reference/android/app/Activity.html#hasWindowFocus()) vous renvoie le booléen dont vous avez besoin.

public class ActivityForegroundChecker extends TimerTask
{
    private static final long FOREGROUND_CHECK_PERIOD = 5000;
    private static final long FIRST_DELAY             = 3000;

    private Activity m_activity;
    private Timer    m_timer;

    public ActivityForegroundChecker (Activity p_activity)
    {
        m_activity = p_activity;
    }

    @Override
    public void run()
    {
        if (m_activity.hasWindowFocus() == true) {
            // Activity is on foreground
            return;
        }
        // Activity is on background.
    }

    public void start ()
    {
        if (m_timer != null) {
            return;
        }
        m_timer = new Timer();
        m_timer.schedule(this, FIRST_DELAY, FOREGROUND_CHECK_PERIOD);
    }

    public void stop ()
    {
        if (m_timer == null) {
            return;
        }
        m_timer.cancel();
        m_timer.purge();
        m_timer = null;
    }
}

Voici un exemple de classe pour vérifier la visibilité de vos activités où que vous soyez.

N'oubliez pas que si vous montrez un dialogue le résultat sera faux puisque le dialogue sera le point central. Sinon, c'est vraiment pratique et plus fiable que les solutions suggérées.

10voto

Muzikant Points 2073

C'est exactement la différence entre onPause y onStop les événements de l'activité tels que décrits dans le Documentation de la classe d'activité .

Si je comprends bien, ce que vous voulez faire, c'est appeler finish() de votre activité onStop pour y mettre fin. Voir l'image ci-jointe de la Application de démonstration du cycle de vie des activités . Voici à quoi cela ressemble lorsque l'activité B est lancée à partir de l'activité A. L'ordre des événements est de bas en haut, vous pouvez donc voir que l'Activité A onStop est appelé après l'activité B onResume a déjà été appelé.

Activity lifecycle demo

Si un dialogue est affiché, votre activité est atténuée en arrière-plan et seulement onPause s'appelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X