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.

8voto

avianey Points 532

Deux solutions possibles :

1) Rappels du cycle de vie des activités

Utilisez un Application qui met en œuvre ActivityLifecycleCallbacks et l'utiliser pour suivre les événements du cycle de vie des activités dans votre application. Notez que ActivityLifecycleCallbacks sont pour Android api >= 14. Pour les api Android antérieures, vous devrez l'implémenter vous-même dans toutes vos activités ;-)

Utilisez Application lorsque vous avez besoin de partager / stocker des états à travers les activités.

2) Vérifier les informations sur les processus en cours

Vous pouvez vérifier l'état d'un processus en cours d'exécution avec cette classe RunningAppProcessInfo

Récupérer la liste des processus en cours avec ActivityManager.getRunningAppProcesses() et filtrer la liste des résultats pour rechercher le RunningAppProcessInfo souhaité et vérifier son "importance".

4voto

kiran boghra Points 494

J'ai créé un projet sur github app-foreground-background-listen

qui utilise une logique très simple et fonctionne bien avec tous les niveaux de l'API Android.

3voto

Kit Points 31

Utilisez l'intervalle de temps entre la pause et la reprise depuis l'arrière-plan pour déterminer s'il est réveillé depuis l'arrière-plan.

Dans l'application personnalisée

private static boolean isInBackground;
private static boolean isAwakeFromBackground;
private static final int backgroundAllowance = 10000;

public static void activityPaused() {
    isInBackground = true;
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (isInBackground) {
                isAwakeFromBackground = true;
            }
        }
    }, backgroundAllowance);
    Log.v("activity status", "activityPaused");
}

public static void activityResumed() {
    isInBackground = false;
    if(isAwakeFromBackground){
        // do something when awake from background
        Log.v("activity status", "isAwakeFromBackground");
    }
    isAwakeFromBackground = false;
    Log.v("activity status", "activityResumed");
}

Dans la classe BaseActivity

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

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

3voto

EliaszKubala Points 82

Je pense avoir une meilleure solution. Parce que vous pouvez intégrer simplement MyApplication.activityResumed() ; à chaque activité par un extend.

Tout d'abord, vous devez créer (comme CyberneticTwerkGuruOrc)

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

Ensuite, vous devez ajouter la classe Application à AndroidManifest.xml

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

Ensuite, créez la classe ActivityBase

public class ActivityBase extends Activity {

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

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

Enfin, lorsque vous créez une nouvelle activité, vous pouvez simplement l'étendre par ActivityBase au lieu d'Activity.

public class Main extends ActivityBase {
    @Override
    protected void onResume() {
        super.onResume();
    }

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

Pour moi, c'est la meilleure méthode, car vous devez juste vous souvenir de extend by ActivityBase. En outre, vous pouvez étendre votre fonction de base à l'avenir. Dans mon cas, j'ai ajouté des récepteurs pour mon service et des alertes sur le réseau dans une seule classe.

Si vous voulez vérifier la visibilité de votre application, vous pouvez simplement appeler

MyApplication.isActivityVisible()

2voto

Ramz Points 1575

On peut y parvenir d'une manière efficace en utilisant Application.ActivityLifecycleCallbacks

Par exemple, prenons le nom de la classe Activity comme ProfilActivité permet de savoir si elle est en avant-plan ou en arrière-plan.

Tout d'abord, nous devons créer notre classe d'application en étendant Classe d'application

qui met en œuvre

Application.ActivityLifecycleCallbacks

Soit ma classe d'application comme suit

Classe d'application

public class AppController extends Application implements Application.ActivityLifecycleCallbacks {

private boolean activityInForeground;

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

//register ActivityLifecycleCallbacks  

    registerActivityLifecycleCallbacks(this);

}

public static boolean isActivityVisible() {
    return activityVisible;
}

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

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

private static boolean activityVisible;

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

}

@Override
public void onActivityStarted(Activity activity) {

}

@Override
public void onActivityResumed(Activity activity) {
    //Here you can add all Activity class you need to check whether its on screen or not

    activityInForeground = activity instanceof ProfileActivity;
}

@Override
public void onActivityPaused(Activity activity) {

}

@Override
public void onActivityStopped(Activity activity) {

}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

}

@Override
public void onActivityDestroyed(Activity activity) {

}

public boolean isActivityInForeground() {
    return activityInForeground;
}
}

dans la classe ci-dessus il y a une méthode de surcharge onActivityResumed de ActivityLifecycleCallbacks

 @Override
public void onActivityResumed(Activity activity) {
    //Here you can add all Activity class you need to check whether its on screen or not

    activityInForeground = activity instanceof ProfileActivity;
}

où l'on peut trouver toutes les instances d'activité qui sont actuellement affichées à l'écran, il suffit de vérifier si votre activité est à l'écran ou non par la méthode ci-dessus.

Enregistrez votre classe d'application dans manifest.xml

<application
    android:name=".AppController" />

Pour vérifier si l'activité est à l'avant-plan ou à l'arrière-plan comme dans la solution ci-dessus, appelez la méthode suivante aux endroits que vous devez vérifier

AppController applicationControl = (AppController) getApplicationContext();
    if(applicationControl.isActivityInForeground()){
     Log.d("TAG","Activity is in foreground")
    }
    else
    {
      Log.d("TAG","Activity is in background")
    }

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