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

104

J'ai un écran de démarrage sur une minuterie. Mon problème est qu'avant finish()mon activité, je dois vérifier que l'activité suivante a commencé car une boîte de dialogue système apparaît et je veux 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 des boîtes de dialogue en plus de l'activité.

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

le rouge est mon activité qui est en arrière-plan tandis que le dialogue est au premier plan

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

pseudo
la source
Peut être pertinent: stackoverflow.com/questions/4414171/…
jarmod
Pour clarifier, vous souhaitez lancer un sélecteur d'intention et attendre que votre application se termine () jusqu'à ce que l'utilisateur ait appuyé sur l'un des choix? Il semble que vous ayez besoin de Intent.createChooser () et startActivityForResult () suivis de finish () lorsque le résultat est reçu.
alanv
duplication possible de Vérifier si une application Android fonctionne en arrière
Douglas Nassif Roma Junior
ProcessLifecycleOwner est la nouvelle solution
SR

Réponses:

189

Voici ce qui est recommandé comme la bonne solution:

La bonne solution (les crédits vont à Dan, CommonsWare et NeTeInStEiN) Suivez la visibilité de votre application par vous-même en utilisant les 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'application ou d'un service (il existe également quelques variantes de cette solution si vous souhaitez vérifier la visibilité de l'activité du service).

Exemple Implémentez la classe 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()méthode, vous souhaitez utiliser isActivityVisible()pour vérifier si l'activité est visible ou non. Là, 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 mauvaises solutions ... alors évitez de faire cela.

Source: stackoverflow

Mais je ne suis pas une classe wrapper
la source
Il y a un petit moment entre la fin et le début de l'activité et j'ai besoin d'ajouter un peu de retard et de contre
sagus_helgy
28
Cela ne fonctionne pas de manière fiable. Vous pouvez avoir la situation suivante: Reprendre A Reprendre B Pause A. Désormais, activityVisible est false alors que l'application est visible. Vous utilisez peut-être un compteur de visibilité: visibleCounter ++ dans onResume et visibleCounter - dans onPause.
Joris Weimar
4
Convenu avec Joris Weimar que ce n'est pas une solution infaillible. Un scénario est si l'utilisateur tiré vers le bas le panneau de notification, alors ni le onPause, onStopni l' onResumeévénement est appelé. Alors, que faites-vous si aucun de ces événements n'est déclenché?!
1
En fait, aucune des autres réponses ne fonctionne à 100% non plus.
2
Si l'application a plus d'une activité, ce schéma ne fonctionnera pas. Remplacer par des compteurs au moins
ruX
70

Si vous ciblez le niveau d'API 14 ou supérieur, vous pouvez 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
    ....
}
souris argentée
la source
18
Vous pouvez simplement le faire dans les rappels réguliers du cycle de vie de l'activité (onResume (), onStop ()) aussi je dirais.
Daniel Wilson
5
@DanielWilson Je pense que le but n'est pas de construire un système pour faire quelque chose là où il en existe déjà. IMHO cela devrait être la réponse acceptée.
Jeffrey Blattman
26

UPD : mis à jour à l'état Lifecycle.State.RESUMED. Merci à @htafoya pour cela.

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

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

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

Alex Misiulia
la source
2
Pas vraiment, il vaut probablement mieux placer activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) ou COMMENCER. INITIALIZEDne garantit pas qu'il est au premier plan.
htafoya
11

Activity :: 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 affichez une boîte de dialogue , le résultat sera faux car la boîte de dialogue aura le focus principal. À part cela, c'est vraiment pratique et plus fiable que les solutions suggérées.

Jour de Burak
la source
1
Merci d'avoir modifié la réponse @Burak Day, c'est en fait une réponse maintenant
Nick
Cela ne fonctionne pas, je préfère utiliser une propriété booléenne dans la classe, définie sur true dans OnResume et définie sur false dans OnPause ();
Chandler
@Chandler quel est le problème exact que vous rencontrez avec ce code? Quelle version également?
Burak Day
@Chandler aussi, que faire si vous n'avez pas accès aux méthodes de cycle de vie des activités. Considérez que vous vérifiez simplement la visibilité de l'activité à partir d'une bibliothèque.
Burak Day
Le vrai problème de cette réponse est que cela ne fonctionne PAS, activity.hasWindowFocus est vrai ne peut pas garantir que l'activité est entre l'état onResume et onPause. Je recommanderais plutôt d'ajouter une propriété bool isResumed dans cette activité, de définir manuellement la valeur et d'ajouter une méthode get.
Chandler
10

C'est exactement la différence entre onPauseet les onStopévénements de l'activité, comme décrit dans la documentation de la classe d'activité .

Si je vous comprends bien, ce que vous voulez faire est d'appeler finish()depuis votre activité onStoppour y mettre fin. Voir l'image ci-jointe de l' application de démonstration Activity Lifecycle . 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 afin que vous puissiez voir que l'activité A onStopest appelée après que l'activité B onResumea déjà été appelée.

Démo du cycle de vie des activités

Si une boîte de dialogue s'affiche, votre activité est grisée en arrière-plan et onPauseest uniquement appelée.

Muzikant
la source
7

Deux solutions possibles:

1) Rappels d'activité LifeCycle

Utilisez une application qui implémente ActivityLifecycleCallbacks et utilisez-la pour suivre les événements du cycle de vie des activités dans votre application. Notez que ActivityLifecycleCallbacks sont pour l'API Android> = 14. Pour les API Android précédentes, vous devrez l'implémenter vous-même dans toutes vos activités ;-)

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

2) Vérifiez les informations du processus en cours d'exécution

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

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

avianey
la source
3

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 une 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();
}
Trousse
la source
3

Je pense que j'ai une meilleure solution. Parce que vous pouvez créer simplement MyApplication.activityResumed (); à chaque activité par une extension.

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'Activité.

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

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

Pour moi, c'est une meilleure méthode car vous devez simplement vous souvenir de extend by ActivityBase. De plus, 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 classe.

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

MyApplication.isActivityVisible()
Eliasz Kubala
la source
Que faire si j'ai besoin de mes activités pour étendre AppCombatActivity?
winklerrr
2

Cela peut atteindre cet objectif de manière efficace en utilisant Application.ActivityLifecycleCallbacks

Par exemple, prenons le nom de la classe Activity comme ProfileActivity, permet de savoir s'il est au premier plan ou en arrière-plan

nous devons d'abord créer notre classe d'application en étendant la classe d'application

qui met en œuvre

Application.ActivityLifecycleCallbacks

Soyons 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 un méthord de substitution 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ù toutes les instances d'activité actuellement affichées à l'écran peuvent être trouvées, vérifiez simplement si votre activité est à l'écran ou non par la méthode ci-dessus.

Enregistrez votre classe Application dans manifest.xml

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

Pour vérifier la météo, l'activité est au premier plan ou en arrière-plan selon la solution ci-dessus, appelez la méthode suivante sur les 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")
    }
Ramz
la source
1

Si vous voulez savoir si une activité de votre application est visible à l'écran, vous pouvez faire quelque chose comme ceci:

public class MyAppActivityCallbacks implements Application.ActivityLifecycleCallbacks {
private Set<Class<Activity>> visibleActivities = new HashSet<>();

@Override
public void onActivityResumed(Activity activity) {
    visibleActivities.add((Class<Activity>) activity.getClass());
}

@Override
public void onActivityStopped(Activity activity) {
     visibleActivities.remove(activity.getClass());
}

public boolean isAnyActivityVisible() {
    return !visibleActivities.isEmpty();
}

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

@Override
public void onActivityStarted(Activity activity) {}

@Override
public void onActivityPaused(Activity activity) {}

@Override
public void onActivityDestroyed(Activity activity) {}

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

Créez simplement un singleton de cette classe et définissez-le dans votre instance d'application comme ci-dessous:

class App extends Application{
     @Override
     public void onCreate() {
         registerActivityLifecycleCallbacks(myAppActivityCallbacks);
     }
}

Ensuite, vous pouvez utiliser la méthode isAnyActivityVisible () de votre instance MyAppActivityCallbacks partout!

Vasil Stolyarchuk
la source
0

avez-vous essayé de ne pas appeler finish et de mettre "android: noHistory =" true "dans le manifeste? cela empêchera l'activité d'aller dans la pile.

shaish
la source
0

Je dois dire que votre flux de travail n'est pas d'une manière Android standard. Sous Android, vous n'avez pas besoin de finish()votre activité si vous souhaitez ouvrir une autre activité depuis Intent. En ce qui concerne la commodité de l'utilisateur, Android permet à l'utilisateur d'utiliser la touche `` retour '' pour revenir de l'activité que vous avez ouverte à votre application.

Alors laissez simplement le système arrêter votre activité et enregistrez tout ce dont vous avez besoin lorsque votre activité est rappelée.

Owen Zhao
la source
3
"Mais ce n'est pas l'androïde", les réponses sont fastidieuses et ne répondent pas à la question posée en premier lieu. de plus, il existe des raisons valables de terminer (); - par exemple, il est concevable que d'y revenir une fois que l'action a pris effet ne sert à rien. en d'autres termes, pensez-vous qu'ils y mettent finish () pour le plaisir? c'est exactement ce que le poseur de question voulait éviter de rester sur la pile
Lassi Kinnunen
"Mais ce n'est pas l'androïde", les réponses sont fastidieuses et ne répondent pas à la question posée en premier lieu. Votre recommandation était injuste. Bien que je l'ai souligné, ce n'était pas la manière Android, j'ai donné la réponse après cette phrase au lieu de rien. Je n'ai tout simplement pas donné la réponse dans le code car c'était inutile. Il était donc injuste de dire que je n'ai pas répondu à la question en premier lieu.
Owen Zhao il y a
0

Enregistrez un indicateur si vous êtes en pause ou repris. Si vous êtes repris, cela signifie que vous êtes au premier plan

boolean  isResumed = false;

@Override
public void onPause() {
  super.onPause();    
  isResumed = false;
}

@Override
public void onResume() {
  super.onResume();    
  isResumed = true;
}

private void finishIfForeground() {
  if (isResumed) {
    finish();
  }
}
yoah
la source
0

Une solution possible pourrait être de définir un indicateur lors de l'affichage de la boîte de dialogue système, puis dans la méthode onStop du cycle de vie de l'activité, vérifiez l'indicateur, si vrai, terminez l'activité.

Par exemple, si la boîte de dialogue système est déclenchée par un clic sur un bouton, l'écouteur onclick peut ressembler à

private OnClickListener btnClickListener = new OnClickListener() {

    @Override
    public void onClick(View v) {           
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setType("text/plain");
        CheckActivity.this.startActivity(Intent.createChooser(intent, "Complete action using"));
        checkFlag = true;  //flag used to check

    }
};

et en arrêt d'activité:

@Override
protected void onStop() {
    if(checkFlag){
        finish();
    }
    super.onStop();
}
Diya
la source
0

Pourquoi ne pas utiliser les émissions pour cela? la deuxième activité (celle qui doit être active) peut envoyer une diffusion locale comme celle-ci:

//put this in onCreate(..) or any other lifecycle method that suits you best
//notice the string sent to the intent, it will be used to register a receiver!
Intent result = new Intent("broadcast identifier");
result.putString("some message");//this is optional
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(result);

puis écrivez un récepteur simple dans l'activité de démarrage:

//this goes on the class level (like a class/instance variable, not in a method) of your splash activity:
private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //kill activity here!!!
        //mission accomplished!
    }
};

et enregistrez votre nouveau récepteur auprès du LocalBroadcastManager pour écouter l'émission de votre deuxième activité:

//notice the string sent to the intent filter, this is where you tell the BroadcastManager which broadcasts you want to listen to!
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(receiver, new IntentFilter("broadcast identifier"));

Notez que vous pouvez utiliser une ressource constante ou chaîne pour la chaîne «identificateur de diffusion».


la source
Pour une meilleure efficacité des annonces de sécurité, utilisez LocalBroadcastManagerici
Alexander Farber
0

Si vous utilisez finish()simplement pour éviter qu'une nouvelle application ne démarre dans la pile (tâche) de votre application, vous pouvez utiliser l' Intent.FLAG_ACTIVITY_NEW_TASKindicateur lors du démarrage d'une nouvelle application et ne pas appeler finish()du tout. D'après la documentation , c'est le drapeau à utiliser pour implémenter un comportement de style "lanceur".

// just add this line before you start an activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Sergej Shafarenka
la source
0

Utilisez ces méthodes dans un fichier Activity.

isDestroyed()

Ajouté dans Api 17
Renvoie true si l'appel final onDestroy () a été effectué sur l'activité, donc cette instance est maintenant morte.

isFinishing()

Ajouté dans Api 1
Vérifiez si cette activité est en cours de fin, soit parce que vous avez appelé finish () dessus, soit parce que quelqu'un d'autre a demandé qu'elle se termine. Ceci est souvent utilisé dans onPause () pour déterminer si l'activité est simplement en pause ou complètement terminée.


À partir de la documentation sur les fuites de mémoire

Une erreur courante avec AsyncTaskest de capturer une référence forte à l'hôte Activity(ou Fragment):

class MyActivity extends Activity {
  private AsyncTask<Void, Void, Void> myTask = new AsyncTask<Void, Void, Void>() {
    // Don't do this! Inner classes implicitly keep a pointer to their
    // parent, which in this case is the Activity!
  }
}

C'est un problème car il AsyncTaskpeut facilement survivre au parent Activity, par exemple si un changement de configuration se produit pendant l'exécution de la tâche.

La bonne façon de faire est de faire de votre tâche une staticclasse, qui ne capture pas le parent, et contenant une référence faible à l'hôte Activity:

class MyActivity extends Activity {
  static class MyTask extends AsyncTask<Void, Void, Void> {
    // Weak references will still allow the Activity to be garbage-collected
    private final WeakReference<MyActivity> weakActivity;

    MyTask(MyActivity myActivity) {
      this.weakActivity = new WeakReference<>(myActivity);
    }

    @Override
    public Void doInBackground(Void... params) {
      // do async stuff here
    }

    @Override
    public void onPostExecute(Void result) {
      // Re-acquire a strong reference to the activity, and verify
      // that it still exists and is active.
      MyActivity activity = weakActivity.get();
      if (activity == null
          || activity.isFinishing()
          || activity.isDestroyed()) {
        // activity is no longer valid, don't do anything!
        return;
      }

      // The activity is still valid, do main-thread stuff here
    }
  }
}
Sanket Berde
la source
0

Voici une solution utilisant la Applicationclasse.

public class AppSingleton extends Application implements Application.ActivityLifecycleCallbacks {

private WeakReference<Context> foregroundActivity;


@Override
public void onActivityResumed(Activity activity) {
    foregroundActivity=new WeakReference<Context>(activity);
}

@Override
public void onActivityPaused(Activity activity) {
    String class_name_activity=activity.getClass().getCanonicalName();
    if (foregroundActivity != null && 
            foregroundActivity.get().getClass().getCanonicalName().equals(class_name_activity)) {
        foregroundActivity = null;
    }
}

//............................

public boolean isOnForeground(@NonNull Context activity_cntxt) {
    return isOnForeground(activity_cntxt.getClass().getCanonicalName());
}

public boolean isOnForeground(@NonNull String activity_canonical_name) {
    if (foregroundActivity != null && foregroundActivity.get() != null) {
        return foregroundActivity.get().getClass().getCanonicalName().equals(activity_canonical_name);
    }
    return false;
}
}

Vous pouvez simplement l'utiliser comme suit,

((AppSingleton)context.getApplicationContext()).isOnForeground(context_activity);

Si vous avez une référence à l'activité requise ou que vous utilisez le nom canonique de l'activité, vous pouvez savoir si elle est au premier plan ou non. Cette solution n'est peut-être pas infaillible. Par conséquent, vos commentaires sont vraiment les bienvenus.

TMtech
la source
0

Je ne sais pas pourquoi personne n'a parlé de sharedPreferences, pour l'activité A, définir une SharedPreference comme celle-ci (par exemple dans onPause ()):

SharedPreferences pref = context.getSharedPreferences(SHARED_PREF, 0);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("is_activity_paused_a", true);
editor.commit();

Je pense que c'est le moyen fiable de suivre la visibilité des activités.

HZDI
la source
0

Serait Activity.onWindowFocusChanged(boolean hasFocus)utile ici? Cela, plus un indicateur au niveau de la classe, quelque chose comme isFocusedcelui onWindowFocusChangeddéfini, serait un moyen facile de dire à tout moment de votre activité si elle est ciblée ou non. À la lecture de la documentation, il semble que cela définirait correctement «faux» dans toute situation où l'activité n'est pas directement au «premier plan» physique, comme si une boîte de dialogue est affichée ou si la barre de notification est abaissée.

Exemple:

boolean isFocused;
@Override
void onWindowFocusChanged (boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    isFocused = hasFocus;
}

void someMethod() {
    if (isFocused) {
        // The activity is the foremost object on the screen
    } else {
        // The activity is obscured or otherwise not visible
    }
}
Folie
la source
0

Si vous utilisez EventBus , il s'agit d'une méthode appelée hasSubscriberForEventqui peut être utilisée pour vérifier si un Activityest focalisé.

Kris B
la source
-3

J'avais l'habitude de faire comme,

si l'activité n'est pas au premier plan

getIntent ()

renverra null. : = P

Jacob Abraham
la source