Aktivitenin ön planda mı yoksa görünür arka planda mı olduğu nasıl kontrol edilir?


104

Bir zamanlayıcıda açılış ekranım var. Benim sorunum şu ki, finish()aktivitemden önce bir sonraki aktivitenin başladığını kontrol etmem gerekiyor çünkü bir sistem diyalog kutusu açılıyor ve sadece şunu yapmak istiyorum finish(); kullanıcı diyalog kutusundan bir seçenek seçtikten sonra?

Aktivitenizin ön planda olup olmadığını nasıl göreceğime dair birçok soru olduğunu biliyorum, ancak bunun aktivitenin tepesinde diyalog kutularına izin verip vermediğini bilmiyorum.

İşte sorun, diyalog ön plandayken arka planda olan kırmızı benim aktivitem:

kırmızı, diyalog ön plandayken arka planda olan etkinliğimdir

DÜZENLEME: Kullanmamayı denedim, finish()ancak daha sonra aktivitem kaçınmaya çalıştığım uygulamalar yığınına geri dönebilir.



Açıklığa kavuşturmak için, bir amaç seçici başlatmak ve uygulamanızın bitmesini (), kullanıcı seçeneklerden birine dokunana kadar mı beklemek istiyorsunuz? Sonuç alındığında Intent.createChooser () ve startActivityForResult () ve ardından finish () 'e ihtiyacınız var gibi görünüyor.
alanv


ProcessLifecycleOwner en yeni çözüm
SR

Yanıtlar:


189

Doğru çözüm olarak önerilen budur :

Doğru çözüm (krediler Dan, CommonsWare ve NeTeInStEiN'e gider) Activity.onPause, Activity.onResume yöntemlerini kullanarak uygulamanızın görünürlüğünü kendiniz izleyin. "Görünürlük" durumunu başka bir sınıfta saklayın. İyi seçimler, Uygulama veya Hizmetin kendi uygulamanızdır (hizmetten etkinlik görünürlüğünü kontrol etmek isterseniz, bu çözümün birkaç çeşidi de vardır).

Örnek Özel Uygulama sınıfını uygulayın (isActivityVisible () statik yöntemine dikkat edin):

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

Uygulama sınıfınızı AndroidManifest.xml'de kaydedin:

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

Projedeki her Aktiviteye onPause ve onResume ekleyin (isterseniz Aktiviteleriniz için ortak bir ata oluşturabilirsiniz, ancak aktiviteniz MapActivity / ListActivity vb .'den zaten genişletilmişse, yine de aşağıdakileri elle yazmanız gerekir) :

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

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

Senin içinde finish()yöntemle, kullanmak istediğiniz isActivityVisible()etkinlik görünür olup olmadığını kontrol etmek. Orada kullanıcının bir seçeneği seçip seçmediğini de kontrol edebilirsiniz. Her iki koşul da karşılandığında devam edin.

Kaynak ayrıca iki yanlış çözümden bahsediyor ... bu yüzden bunu yapmaktan kaçının.

Kaynak: stackoverflow



28
Bu güvenilir bir şekilde çalışmıyor. Aşağıdaki durumla karşılaşabilirsiniz: Sürdür A Devam Et B Duraklat A. Şimdi activityVisible yanlıştır, ancak uygulama görünür durumdadır. Belki bir görünürlük sayacı kullanırsınız: onResume'da visibleCounter ++ ve onPause'da visibleCounter.
Joris Weimar

4
İle Anlaştık Joris Weimar bu olduğunu değil kusursuz bir çözüm. Bir senaryo Kullanıcı daha sonra, bildirim panelini aşağı çekti eğer ne onPause, onStopne de onResumeolay denir. Peki bu olaylardan hiçbiri ateşlenmezse ne yaparsınız ?!

1
Aslında, diğer cevapların hiçbiri de% 100 işe yaramıyor.

2
Uygulamanın birden fazla Aktivitesi varsa, bu şema çalışmayacaktır. En az sayaçlarla değiştirin
ruX

70

API düzeyi 14 veya üzeri hedefleniyorsa android.app.Application.ActivityLifecycleCallbacks kullanılabilir.

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

18
Bunu normal etkinlik yaşam döngüsü geri çağırmalarında (onResume (), onStop ()) da yapabilirsiniz diyebilirim.
Daniel Wilson

5
@DanielWilson Bence önemli olan, zaten var olan bir şeyi yapmak için bir sistem kurmak değil. IMHO bu kabul edilen cevap olmalıdır.
Jeffrey Blattman

26

UPD : duruma güncellendi Lifecycle.State.RESUMED. Bunun için @ htafoya'ya teşekkürler .

2019'da yeni destek kitaplığı 28+veya AndroidX yardımıyla şunları kullanabilirsiniz:

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

Kaputun altında neler olduğunu anlamak için dokümantasyonda daha fazlasını okuyabilirsiniz .


2
Pek değil, muhtemelen yerleştirmek activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) veya BAŞLAMAK daha iyidir . INITIALIZEDön planda olduğunu garanti etmez.
htafoya

11

Activity :: hasWindowFocus () size ihtiyacınız olan boole değerini döndürür.

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

İşte nerede olursanız olun faaliyetlerinizin görünürlüğünü kontrol etmek için örnek bir sınıf.

Bir diyalog gösterirseniz, diyaloğun ana odak noktası olacağından sonucun yanlış olacağını unutmayın. Bunun dışında gerçekten kullanışlı ve önerilen çözümlerden daha güvenilir.


1
@ Burak Günü cevabını değiştirdiğiniz için teşekkür ederiz, bu aslında şimdi bir cevap
Nick

Bu işe yaramaz, sınıfta bir boole özelliği kullanmayı, OnResume'da true olarak ve OnPause () 'da false olarak ayarlamayı tercih ederim;
Chandler

@Chandler Bu kodla yaşadığınız sorunun tam olarak nedir? Ayrıca hangi versiyon?
Burak Günü

@Chandler ayrıca, aktivite yaşam döngüsü yöntemlerine erişiminiz yoksa ne olur? Sadece bir kütüphaneden aktivitenin görünürlüğünü kontrol ettiğinizi düşünün.
Burak Günü

Bu cevabın gerçek problemi işe yaramıyor, activity.hasWindowFocus doğrudur, aktivitenin onResume ve onPause durumu arasında olduğunu garanti edemez. Bu etkinliğe bir bool isResumed özelliği eklemenizi, değeri manuel olarak ayarlamanızı ve bir get yöntemi eklemenizi tavsiye ederim.
Chandler

10

Bu tam olarak aramdaki fark onPauseve onStopanlatıldığı gibi faaliyet olaylar Etkinlik sınıfı belgeler .

Sizi doğru anlıyorsam, yapmak istediğiniz şey, finish()faaliyetinizi onStopsonlandırmak için çağrı yapmaktır . Activity Lifecycle Demo Uygulamasının ekli resmine bakın . Aktivite A'dan Aktivite B başlatıldığında böyle görünüyor. Olayların sıralaması aşağıdan yukarıya doğru olduğundan Aktivite A'nın onStopAktivite B onResumezaten çağrıldıktan sonra çağrıldığını görebilirsiniz.

Etkinlik yaşam döngüsü demosu

Bir iletişim kutusunun görüntülenmesi durumunda, etkinliğiniz arka planda karartılır ve yalnızca onPausearanır.


7

Olası iki çözüm:

1) Etkinlik Yaşam Döngüsü Geri Aramaları

ActivityLifecycleCallbacks'i uygulayan bir Uygulama kullanın ve bunu uygulamanızdaki Aktiviteler yaşam döngüsü olaylarını izlemek için kullanın. ActivityLifecycleCallbacks'in Android api> = 14 için olduğunu unutmayın. Önceki Android api için, bunu tüm etkinliklerinizde kendiniz uygulamanız gerekir ;-)

Faaliyetler arasında durumları paylaşmanız / saklamanız gerektiğinde Uygulamayı kullanın .

2) Çalışan işlem bilgilerini kontrol edin

Bu sınıf RunningAppProcessInfo ile çalışan bir işlemin durumunu kontrol edebilirsiniz.

ActivityManager.getRunningAppProcesses () ile çalışan işlem listesini getirin ve istenen RunningAppProcessInfo'yu kontrol etmek ve "önemini" kontrol etmek için sonuç listesini filtreleyin



3

Arka plandan uyanık olup olmadığını belirlemek için duraklatma ve arka plandan devam ettirme arasındaki zaman boşluğunu kullanın

Özel Uygulamada

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

BaseActivity Sınıfında

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

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

3

Sanırım daha iyi bir çözümüm var. Çünkü basitçe MyApplication.activityResumed (); her Faaliyete bir ölçüde.

Öncelikle oluşturmalısınız (CyberneticTwerkGuruOrc gibi)

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

Ardından, AndroidManifest.xml'e Uygulama sınıfı eklemeniz gerekir.

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

Ardından ActivityBase sınıfı oluşturun

public class ActivityBase extends Activity {

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

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

Son olarak, yeni Activity sandığınızda, ActivityBase yerine ActivityBase ile genişletebilirsiniz.

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

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

Benim için daha iyi bir yöntem çünkü ActivityBase ile genişletmeyi hatırlamanız gerekiyor. Ek olarak, gelecekte temel işlevinizi genişletebilirsiniz. Benim durumumda, hizmetim için alıcılar ve bir sınıfta ağ hakkında uyarılar ekledim.

Uygulamanızın görünürlüğünü kontrol etmek istiyorsanız, aramanız yeterlidir

MyApplication.isActivityVisible()

AppCombatActivity'yi genişletmek için Etkinliklerime ihtiyacım olursa ne olur?
winklerrr

2

Bu, Application.ActivityLifecycleCallbacks kullanarak verimli bir şekilde bunu başarabilir.

Örneğin, ProfileActivity olarak Activity sınıf adını alalım , ön planda mı yoksa arka planda mı olduğunu bulalım

İlk başta uzatarak bizim uygulama sınıfı oluşturmak gerekir Uygulama Class

hangi uygular

Application.ActivityLifecycleCallbacks

Uygulama sınıfım aşağıdaki gibi olalım

Uygulama sınıfı

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

Yukarıdaki sınıftaki bir geçersiz kılma methord vardır onActivityResumed arasında 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 anda ekranda görüntülenen tüm aktivite vakalarının bulunabileceği yerlerde, yukarıdaki yöntemle Aktivitenizin Ekranda olup olmadığını kontrol edin.

Uygulama sınıfınızı manifest.xml'de kaydedin

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

Hava durumunu kontrol etmek için Aktivite Ön Plandadır veya yukarıdaki çözüme göre arka plandadır, kontrol etmeniz gereken yerlerde aşağıdaki yöntemi arayın

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

1

Uygulamanızın herhangi bir etkinliğinin ekranda görünüp görünmediğini bilmek istiyorsanız, aşağıdaki gibi bir şey yapabilirsiniz:

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) {}}

Sadece bu sınıftan bir tane oluşturun ve aşağıdaki gibi Uygulama örneğinizde ayarlayın:

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

Daha sonra MyAppActivityCallbacks örneğinizin isAnyActivityVisible () yöntemini her yerde kullanabilirsiniz!


0

finish'i çağırmamayı ve manifest'e "android: noHistory =" true "koymayı denediniz mi? Bu, etkinliğin yığına gitmesini engelleyecektir.


0

İş akışınızın standart bir Android tarzında olmadığını söylemeliyim. Android'de, finish()Intent'ten başka bir etkinlik açmak istiyorsanız etkinliğinize ihtiyacınız yoktur . Kullanıcının rahatlığına gelince, Android, uygulamanıza açtığınız aktiviteden geri dönmek için kullanıcının 'geri' tuşunu kullanmasına izin verir.

Bu nedenle, sistemin faaliyetinizi durdurmasına ve faaliyetiniz geri çağrıldığında ihtiyaç duyduğunuz her şeyi kaydetmesine izin verin.


3
"Buu bu android değil" şeklindeki yanıtlar yorucu ve ilk başta sorulan soruyu cevaplamıyor. ayrıca, bitirmek için geçerli nedenler vardır (); - örneğin, eylem gerçekleştikten sonra ona geri dönmenin hiçbir amaca hizmet etmediği düşünülebilir. başka bir deyişle, eğlenmek için oraya finish () koyduklarını düşünüyor musunuz? soruyu soran kişinin kaçınmak istediği şey yığında kalmak
Lassi Kinnunen

"Buu bu android değil" şeklindeki yanıtlar yorucu ve ilk başta sorulan soruyu cevaplamıyor. Öneriniz haksızlıktı. Bunun Android yolu olmadığını belirtsem de hiçbir şey yerine bu cümleden sonra cevabı verdim. Gereksiz olduğu için cevabı kodla vermedim. Yani ilk başta soruya cevap vermediğimi söylemek haksızlıktı.
Owen Zhao

0

Duraklatılırsanız veya devam ettirilirseniz bir bayrak kaydedin. Devam ederseniz, ön plandasınız demektir

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

0

Olası bir çözüm, sistem iletişim kutusunu gösterirken bir bayrak ayarlamak ve ardından etkinlik yaşam döngüsünün onStop yönteminde bayrağı kontrol edin, eğer doğruysa etkinliği bitirin.

Örneğin, sistem iletişim kutusu bir düğmeye tıklama ile tetiklenirse, onclick dinleyicisi şöyle olabilir:

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

    }
};

ve faaliyetin bitiminde:

@Override
protected void onStop() {
    if(checkFlag){
        finish();
    }
    super.onStop();
}

0

Neden bunun için yayınları kullanmıyorsunuz? ikinci aktivite (tamamlanması gereken) şu şekilde yerel bir yayın gönderebilir:

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

ardından açılış etkinliğine basit bir alıcı yazın:

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

ve ikinci etkinliğinizden yayını dinlemek için yeni alıcınızı LocalBroadcastManager'a kaydedin:

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

"Yayın tanımlayıcı" dizesi için bir sabit veya dize kaynağı kullanabileceğinizi unutmayın.


Daha iyi güvenlik ve reklam verimliliği için LocalBroadcastManagerburayı kullanın
Alexander Farber

0

Yalnızca finish()yeni uygulamanın uygulamanızın yığınında (görevinde) başlamasını önlemek için kullanırsanız , yeni uygulamayı başlatırken Intent.FLAG_ACTIVITY_NEW_TASKbayrak kullanabilirsiniz ve hiç arama yapmayın finish(). Belgelere göre , bu "başlatıcı" tarzı bir davranış uygulamak için kullanılacak bayraktır.

// just add this line before you start an activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

0

Bu yöntemleri bir Activity.

isDestroyed()

Api 17'de eklendi
Activity'de son onDestroy () çağrısı yapılmışsa true döndürür, bu nedenle bu örnek artık ölmüştür.

isFinishing()

Api 1'de eklendi
Bu etkinliğin bitirme sürecinde olup olmadığını kontrol edin, bunun üzerinde bitirmek () 'i çağırdığınızdan veya başka biri bitirmesini istedi. Bu genellikle onPause () 'da etkinliğin sadece duraklatıldığını mı yoksa tamamen bittiğini mi belirlemek için kullanılır.


Gönderen Bellek Kaçaklar Belgeler

Yaygın bir hata AsyncTask, ev sahibine Activity(veya Fragment) güçlü bir referans almaktır :

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

Bu bir sorundur, çünkü örneğin görev çalışırken bir yapılandırma değişikliği meydana gelirse AsyncTask, ebeveynden kolayca daha uzun yaşayabilir Activity.

Bunu yapmanın doğru yolu, görevinizi staticebeveyni yakalayan ve ana makineye zayıf bir referans tutan bir sınıf yapmaktır 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
    }
  }
}

0

İşte Applicationsınıf kullanan bir çözüm .

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

Aşağıdaki gibi basitçe kullanabilirsiniz,

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

Gerekli Aktiviteye bir referansınız varsa veya Aktivitenin kanonik adını kullanıyorsanız, ön planda olup olmadığını öğrenebilirsiniz. Bu çözüm kusursuz olmayabilir. Bu nedenle yorumlarınız çok hoş.


0

Neden hiç kimsenin paylaşılan Tercihler hakkında konuşmadığını bilmiyorum, Etkinlik A için, böyle bir SharedPreference belirleme (örneğin onPause () 'da):

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

Bence bu, faaliyetlerin görünürlüğünü takip etmenin güvenilir bir yolu.


0

Misiniz Activity.onWindowFocusChanged(boolean hasFocus)Burada yararlı olabilir? Yani, artı bir sınıf düzeyinde bayrak, gibi bir şey isFocusedbu onWindowFocusChangedsetleri, o odaklanmış olup olmadığını etkinlik herhangi bir noktada anlatmak için kolay bir yol olacaktır. Dokümanlar okunduğunda, etkinliğin doğrudan fiziksel "ön planda" olmadığı her durumda, örneğin bir iletişim kutusunun görüntülenmesi veya bildirim tepsisinin aşağı çekilmesi gibi, doğru bir şekilde "yanlış" olarak ayarlanmış gibi görünüyor.

Misal:

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

0

EventBus kullanıyorsanız , odaklanmış hasSubscriberForEventolup olmadığını kontrol etmek için kullanılabilen bir yöntem olarak adlandırılır Activity.


-3

Ben severdim

aktivite ön planda değilse

getIntent ()

null döndürür. : = P

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.