Efficiency detect fourground/background states of an app during the lifecycle

Although there are many classic solutions around onPause/onResume ...but this solution doesn't cover all use cases of developers who want to centralize this detection under scoope of app rather than multiple activities & services .

To fix the issue first create an Application class for your app then create a new class let's call it Foreground as implemented below

to resume steps to do :

1)add application class & Foreground class

2)add application class name to manifest (<application android:name="MyApplication")

3)from application class initialize Foreground class

that's all! now you can intercept background/Foreground states in  onActivityStarted and onActivityStopped



Application class

=================


package xx.yy.zz;


import android.app.Application;


/**

 * Created by kboloorian on 05/03/2015.

 */

public class MyApplication extends Application {


    @Override

    public void onCreate(){

        Foreground.init(this);//inittialize Foreground class

    }

}


Foreground class in Foreground.java

===================================


package xx.yy.zz;

/**

 * Created by kboloorian on 05/03/2015.

 */


import android.app.Activity;

import android.app.Activity;

import android.app.Application;

import android.content.Context;

import android.os.Bundle;

import android.util.Log;

import java.util.List;

import java.util.concurrent.CopyOnWriteArrayList;


/**

 * 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(this).addListener(listener);

 *   }

 *

 *   public void onDestroy(){

 *      super.onCreate();

 *      Foreground.get(this).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();


    }


    private static Foreground instance;


    private int refs;

    private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();


    /**

     * 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

     * @return an initialised Foreground instance

     */

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

    }


    public static Foreground get(){

        if (instance == null) {

            throw new IllegalStateException(

                    "Foreground is not initialised - invoke " +

                            "at least once with parameterised init/get");

        }

        return instance;

    }


    public boolean isForeground(){

        return refs > 0;

    }


    public boolean isBackground(){

        return refs == 0;

    }


    public void addListener(Listener listener){

        listeners.add(listener);

    }


    public void removeListener(Listener listener){

        listeners.remove(listener);

    }


//callback for foureground detection

    @Override

    public void onActivityStarted(Activity activity) {

        if (++refs == 1){

            for (Listener l : listeners) {

                try {

                    l.onBecameForeground();

                } catch (Exception exc) {

                    Log.e(TAG, "Listener threw exception!", exc);

                }

            }

            Log.i(TAG, "became foreground");

            //todo 

        } else {

            Log.i(TAG, "still foreground");

        }

    }

//callback for background detection

    @Override

    public void onActivityStopped(Activity activity) {

        if (--refs == 0) {

            for (Listener l : listeners) {

                try {

                    l.onBecameBackground();

                } catch (Exception exc) {

                    Log.e(TAG, "Listener threw exception!", exc);

                }

            }

            Log.i(TAG, "became background");

            //SDKLoader.unLoad();

        } else {

            Log.i(TAG, "still foreground");

        }

    }


    @Override

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


    @Override

    public void onActivityResumed(Activity activity) {}


    @Override

    public void onActivityPaused(Activity activity) {}


    @Override

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


    @Override

    public void onActivityDestroyed(Activity activity) {



    }

}

 © Xosrov 2016