如何使用Single Activity或Java类检测应用程序运行前台或后台

时间:2017-10-03 05:30:12

标签: java android android-activity

我想向服务器发送报告,这意味着用户在一天内使用该应用程序多久..我可以实现使用此方法

 @Override
    protected void onResume() {
        super.onResume();

        //commonclassMethod.getInstance(UserForground);
    }

    @Override
    protected void onStop() {
        super.onStop();
        //commonclassMethod.getInstance(UserBackground);
    }

我需要在每个活动中调用此方法发生什么......

我需要什么,是否有可能在单个 java类活动中找到用户forground background方法..

先谢谢。

4 个答案:

答案 0 :(得分:2)

你可以通过在扩展Application类的类中添加一个方法isAppIsInBackground(Context context)来实现这个目的

在该类中定义该方法:

public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }
        return isInBackground;
    }

如果应用程序处于后台

,则为真

或者另一个更好的方法是在 BaseActivity的覆盖方法

中,将每个Activity扩展为 BaseActivity
protected void onResume() { 
super.onResume(); 
//commonclassMethod.getInstance(UserForground); 
} 

protected void onStop() { 
super.onStop(); 
//commonclassMethod.getInstance(UserBackground); 
} 

答案 1 :(得分:1)

您可以实现回调方法来解决您的问题。

例如:

首先创建一个接口,然后定义一个方法,该方法将充当回调。在这个例子中,我们将有两个类,一个是classA,另一个是classB

接口:

public interface OnCustomEventListener{
  public void onEvent();   //method, which can have parameters
}

classB中的监听器本身(我们只在classB中设置监听器)

private OnCustomEventListener mListener; //听众字段

//setting the listener
public void setCustomEventListener(OnCustomEventListener eventListener) {
   this.mListener=eventListener;
}
在classA中,我们如何开始监听classB必须告诉的任何内容

classB.setCustomEventListener(new OnCustomEventListener(){
    public void onEvent(){
       //do whatever you want to do when the event is performed.
    }
}); 

我们如何从classB触发事件(例如按下按钮)

if(this.mListener!=null){
   this.mListener.onEvent();
}

以下是一些很好的教程link1link2link3,它们很好地描述了回调和用例。

答案 2 :(得分:1)

创建一个类扩展应用程序并使用registerActivityLifecycleCallbacks()来获取活动生命周期

public class MyApp extends Application {

@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
        @Override
        public void onActivityCreated(Activity activity, Bundle bundle) {

        }

        @Override
        public void onActivityStarted(Activity activity) {

        }

        @Override
        public void onActivityResumed(Activity activity) {

        }

        @Override
        public void onActivityPaused(Activity activity) {
           if(activity.getClass().getSimpleName().equalsIgnoreCase(MainActivity.class.getSimpleName())){

               //Do the required thing here
           }
        }

        @Override
        public void onActivityStopped(Activity activity) {

        }

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

        }

        @Override
        public void onActivityDestroyed(Activity activity) {

        }
    });
  }
}

也不要忘记在清单

中注册活动
<application
    android:name=".MyApp"

答案 3 :(得分:0)

您有两种选择。

1)执行抽象的BaseActivity并使所有活动扩展它。这样,您只能在一个BaseActivity中编写代码,并且所有子活动都会使用它。

2)使用自定义计数器类将应用程序监控到前台。如果您想要复制它,请执行此操作。

 /**
 * Created by App Studio 35 on 6/23/17.
 */
public class AppLifeCycleTracker implements Application.ActivityLifecycleCallbacks {;

    /*///////////////////////////////////////////////////////////////
    // METHODS
    *////////////////////////////////////////////////////////////////
    private static final String TAG = Globals.SEARCH_STRING + AppLifeCycleTracker.class.getSimpleName();
    private static AppLifeCycleTracker INSTANCE;
    private static int numActivitiesInMemory = 0;
    private ArrayList<IAppToForegroundListener> mAppToForegroundListeners;
    private boolean isRefreshing;
    private Object lockAccess = new Object();
    private AlertDialog mAlertDialog = null;


    /*///////////////////////////////////////////////////////////////
    // PROPERTIES
    *////////////////////////////////////////////////////////////////
    private ArrayList<IAppToForegroundListener> getAppToForegroundListeners(){
        return mAppToForegroundListeners == null ? mAppToForegroundListeners = new ArrayList<IAppToForegroundListener>() : mAppToForegroundListeners;

    }
    public boolean getIsRefreshing(){
        return isRefreshing;
    }
    public boolean getAppIsInBackground(){
        return numActivitiesInMemory < 1;

    }


    /*///////////////////////////////////////////////////////////////
    // CONSTRUCTOR
    *////////////////////////////////////////////////////////////////
    private AppLifeCycleTracker(){

    }
    public synchronized static AppLifeCycleTracker getInstance(){
        if(INSTANCE == null){
            INSTANCE = new AppLifeCycleTracker();

        }

        return INSTANCE;

    }


    /*///////////////////////////////////////////////////////////////
    // LIFE CYCLE OVERRIDES
    *////////////////////////////////////////////////////////////////
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {


    }
    @Override
    public void onActivityStarted(final Activity activity) {
        //App went into background, so set a flag to avoid loading while we refresh
        if(numActivitiesInMemory == 0 && !(activity instanceof SplashScreenActivity) && !(activity instanceof CreateAccountActivity)){
            A35Log.v(TAG, "App Returned to Foreground, refreshing Token");
            //first load on splash it goes from 0 to 1 so hold off on splash
            synchronized (lockAccess) {
                isRefreshing = true;

            }

            if (DeviceInfo.getInstance(activity).getIsConnectedToInternet()) {
                CognitoManager.refreshToken(activity, new GenericHandler() {
                    @Override
                    public void onSuccess() {
                        A35Log.v(TAG, "Token Refresh Complete, notifying listeners");
                        //we are good, keep going
                        for(IAppToForegroundListener listener : getAppToForegroundListeners()){
                            listener.onRefreshTokenComplete();

                        }

                        synchronized (lockAccess) {
                            isRefreshing = false;

                        }

                    }

                    @Override
                    public void onFailure(Exception exception) {
                        //boot them to login screen
                        if(activity instanceof LoginActivity || activity instanceof SplashScreenActivity){
                            return;
                        }
                        startLoginActivity(activity);
                        synchronized (lockAccess) {
                            isRefreshing = false;

                        }

                    }
                });

            } else {
                showInternetRequiredDialog(activity);

            }

        }

        numActivitiesInMemory++;

    }
    @Override
    public void onActivityResumed(Activity activity) {


    }
    @Override
    public void onActivityPaused(Activity activity) {


    }
    @Override
    public void onActivityStopped(Activity activity) {
        numActivitiesInMemory--;
        //if numActivities == 0 then you are in the background

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


    }
    @Override
    public void onActivityDestroyed(Activity activity) {


    }


    /*///////////////////////////////////////////////////////////////
    // METHODS
    *////////////////////////////////////////////////////////////////
    public void addAppToForegroundListener(IAppToForegroundListener listener){
        getAppToForegroundListeners().add(listener);

    }
    public void removeAppToForegroundListener(IAppToForegroundListener listener){
        getAppToForegroundListeners().remove(listener);

    }
    private void startLoginActivity(final Activity activity){
        ((AMApplication) activity.getApplication()).logoutCurrentUser(activity, false, false, null, true, null);

    }


    /*///////////////////////////////////////////////////////////////
    // INTERFACES
    *////////////////////////////////////////////////////////////////
    public interface IAppToForegroundListener {

        /*///////////////////////////////////////////////////////////////
        // METHODS
        *////////////////////////////////////////////////////////////////
        void onRefreshTokenComplete();

    }
    private void showInternetRequiredDialog(Activity activity){
        final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle("Error").setMessage("Internet is required to use this app").setNegativeButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if(mAlertDialog != null && mAlertDialog.isShowing()) {
                    mAlertDialog.dismiss();

                }

            }

        });

        mAlertDialog = builder.create();
        mAlertDialog.show();

    }

}

当然,这比你正在寻找的更多一点,因为我的管理人员使用cognito刷新令牌并强制刷新从背景和类似的东西返回,所以只是忽略那一块。但其余的都是一样的。希望有所帮助。

我假设您不需要BaseActivity的示例,所以我不会通过粘贴来光顾您。

在Application类中启动

  @Override
public void onCreate() {
    super.onCreate();
   registerActivityLifecycleCallbacks(AppLifeCycleTracker.getInstance());

}

然后,您只需要从BaseActivity或BaseFragment访问,如果您需要在应用程序处于活动或片段级别的前台或后台时收到通知。对于你的情况并非如此。

但如果你想使用它,只需这样做:

   @Override
public void onAttach(Context context) {
    super.onAttach(context);
    AppLifeCycleTracker.getInstance().addAppToForegroundListener(this);

}
@Override
public void onDetach() {
    super.onDetach();
    AppLifeCycleTracker.getInstance().removeAppToForegroundListener(this);

}

但是,我必须再次强调,只有当你想让你的活动或片段知道应用程序何时回到前台以强制刷新或其他行为时,这部分才是唯一的。如果使用Activity,则将onDetach替换为onDestroy,但对于您的场景,您可以跳过整个代码的最后一部分,但不需要它。

相关问题