All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.launchdarkly.sdk.android.Foreground Maven / Gradle / Ivy

package com.launchdarkly.sdk.android;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;

// From: https://gist.github.com/steveliles/11116937

/**
 * Usage:
 * 

* 1. Get the Foreground Singleton, passing a Context or Application object unless you * are sure that the Singleton has definitely already been initialised elsewhere. *

* 2.a) Perform a direct, synchronous check: Foreground.isForeground() / .isBackground() *

* or *

* 2.b) Register to be notified (useful in Service or other non-UI components): *

* Foreground.Listener myListener = new Foreground.Listener(){ * void onBecameForeground(){ * // ... whatever you want to do * } * void onBecameBackground(){ * // ... whatever you want to do * } * } *

* void onCreate(){ * super.onCreate(); * Foreground.get(this).addListener(listener); * } *

* void onDestroy(){ * super.onCreate(); * Foreground.get(this).removeListener(listener); * } */ class Foreground implements Application.ActivityLifecycleCallbacks { private static final long CHECK_DELAY = 500; interface Listener { void onBecameForeground(); void onBecameBackground(); } private static Foreground instance; private boolean foreground = false; private boolean paused = true; private final HandlerThread listenerThread; private final Handler handler; private final List listeners = new CopyOnWriteArrayList<>(); private Runnable check; Foreground() { listenerThread = new HandlerThread("LDForegroundListener"); listenerThread.start(); handler = new Handler(listenerThread.getLooper()); } /** * Its not strictly necessary to use this method - _usually_ invoking * get with a Context gives us a path to retrieve the Application and * initialise, but sometimes (e.g. in test harness) the ApplicationContext * is != the Application, and the docs make no guarantees. * * @param application Application for registering lifecycle callbacks on * @return an initialised Foreground instance */ static Foreground init(Application application) { if (instance == null) { instance = new Foreground(); ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo(); ActivityManager.getMyMemoryState(appProcessInfo); instance.foreground = appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE; application.registerActivityLifecycleCallbacks(instance); } return instance; } static Foreground get(Application application) { if (instance == null) { init(application); } return instance; } static Foreground get(Context ctx) { if (instance == null) { Context appCtx = ctx.getApplicationContext(); if (appCtx instanceof Application) { init((Application) appCtx); } throw new IllegalStateException("Foreground is not initialised and " + "cannot obtain the Application object"); } return instance; } static Foreground get() { if (instance == null) { throw new IllegalStateException("Foreground is not initialised - invoke " + "at least once with parameterised init/get"); } return instance; } boolean isForeground() { return foreground; } boolean isBackground() { return !foreground; } void addListener(Listener listener) { listeners.add(listener); } void removeListener(Listener listener) { listeners.remove(listener); } @Override public void onActivityResumed(Activity activity) { paused = false; boolean wasBackground = !foreground; foreground = true; if (check != null) { handler.removeCallbacks(check); check = null; } if (wasBackground) { handler.post(() -> { LDConfig.log().d("went foreground"); for (Listener l : listeners) { try { l.onBecameForeground(); } catch (Exception exc) { LDConfig.log().e(exc, "Listener threw exception!"); } } }); } else { LDConfig.log().d("still foreground"); } } @Override public void onActivityPaused(Activity activity) { paused = true; if (check != null) { handler.removeCallbacks(check); check = null; } handler.postDelayed(check = () -> { if (foreground && paused) { foreground = false; LDConfig.log().d("went background"); for (Listener l : listeners) { try { l.onBecameBackground(); } catch (Exception exc) { LDConfig.log().e(exc, "Listener threw exception!"); } } } else { LDConfig.log().d("still background"); } }, CHECK_DELAY); } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy