Skip to content

Instantly share code, notes, and snippets.

@Jween
Created July 22, 2016 10:06
Show Gist options
  • Save Jween/e720d04d47119a886c7dda3cbc8cd361 to your computer and use it in GitHub Desktop.
Save Jween/e720d04d47119a886c7dda3cbc8cd361 to your computer and use it in GitHub Desktop.
Detect If android app is in foreground or not
/**
* 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(){
* public void onBecameForeground(){
* // ... whatever you want to do
* }
* public void onBecameBackground(){
* // ... whatever you want to do
* }
* }
*
* public void onCreate(){
* super.onCreate();
* Foreground.get(getApplication()).addListener(listener);
* }
*
* public void onDestroy(){
* super.onCreate();
* Foreground.get(getApplication()).removeListener(listener);
* }
*/
public class Foreground implements Application.ActivityLifecycleCallbacks {
public static final String TAG = Foreground.class.getName();
public interface Listener {
public void onBecameForeground();
public void onBecameBackground();
}
public interface Binding {
public void unbind();
}
private interface Callback {
public void invoke(Listener listener);
}
private static class Listeners {
private List<WeakReference<Listener>> listeners = new CopyOnWriteArrayList<>();
public Binding add(Listener listener){
final WeakReference<Listener> wr = new WeakReference<>(listener);
listeners.add(wr);
return new Binding(){
public void unbind() {
listeners.remove(wr);
}
};
}
public void each(Callback callback){
List<WeakReference<Listener>> toBeRemoved = new LinkedList<>();
for (Iterator<WeakReference<Listener>> it = listeners.iterator(); it.hasNext();) {
try {
WeakReference<Listener> wr = it.next();
Listener l = wr.get();
if (l != null) {
callback.invoke(l);
} else {
toBeRemoved.add(wr);
}
} catch (Exception exc) {
Log.e(TAG, "Listener threw exception!", exc);
}
}
if (toBeRemoved.size() > 0) {
listeners.removeAll(toBeRemoved);
}
}
}
private static Callback becameForeground = new Callback() {
@Override
public void invoke(Listener listener) {
listener.onBecameForeground();
}
};
private static Callback becameBackground = new Callback() {
@Override
public void invoke(Listener listener) {
listener.onBecameBackground();
}
};
private static Foreground instance;
private int counter = 0;
private boolean counterFix = false;
private Listeners listeners = new Listeners();
public static Foreground init(Application application){
if (instance == null) {
instance = new Foreground();
application.registerActivityLifecycleCallbacks(instance);
}
return instance;
}
public static Foreground get(Application application){
if (instance == null) {
init(application);
}
return instance;
}
public static Foreground get(){
if (instance == null) {
throw new IllegalStateException(
"Foreground is not initialised - first invocation must use parameterised init/get");
}
return instance;
}
public boolean isForeground(){
return counter > 0;
}
public boolean isBackground(){
return counter <= 0;
}
public Binding addListener(Listener listener){
return listeners.add(listener);
}
@Override
public void onActivityResumed(Activity activity) {}
@Override
public void onActivityPaused(Activity activity) {
}
private void increaseCounter() {
if (isBackground()) {
Log.w(TAG, "became foreground");
counter = 1;
listeners.each(becameForeground);
} else {
Log.i(TAG, "still foreground");
counter ++;
}
}
private void decreaseCounter() {
if (counter > 0) {
counter --;
}
if (counter <= 0) {
Log.w(TAG, "went background");
listeners.each(becameBackground);
}
}
@Override
public void onActivityStarted(Activity activity) {
// if configuration is changing, ignore this counter change.
if (counterFix) {
counterFix = false;
return;
}
increaseCounter();
}
@Override
public void onActivityStopped(Activity activity) {
if (activity != null && !activity.isChangingConfigurations()) {
decreaseCounter();
} else {
counterFix = true;
}
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public void onActivityDestroyed(Activity activity) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment