检测应用程序何时打开/恢复

时间:2015-04-28 16:08:00

标签: android data-collection

每次打开/关闭应用程序时,无论是从任务抽屉启动还是从任务抽屉启动,我都希望在服务器上签入和签出用户。有没有办法做到这一点,同时避免在每个活动中调用一个函数?

谢谢!

5 个答案:

答案 0 :(得分:9)

修改

this answer中,matdev提醒我注意通过ProcessLifeCycleOwner收听应用生命周期事件的更现代的方法。见https://developer.android.com/topic/libraries/architecture/lifecycle

因此,为了更好地组织所需的会话管理功能,应使用以下结构。在SessionTracker的{​​{1}}中注册onCreate。然后将与跟踪用户会话相关的功能隔离到MyApplication类。

首先添加到build.gradle

SessionTracker

然后,实施以下内容:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
}

以前的答案

d60402 here提供的答案以及Hanno Binder使用 Application.registerActivityLifecycleCallbacks()注册活动回调的建议使我得到了这个解决方案。

我将应用程序和已注册的回调扩展到Activity方法onPause和onStart,如下所示。在这些方法中,启动/停止计时器(一个活动被退出,其中调用onPause,在调用onStart时输入一个新活动)。旗帜" wasInBackground"当应用确定在后台/前景(真/假)时切换。如果在运行onStart回调时应用程序处于后台," appEntered"叫做。如果onPause和onStart回调之间传递的时间大于指定的时间(给活动转换留出足够的时间)" appExited"调用app会话的地方被调用。

public class MyApplication extends Application {  

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(SessionTracker.getInstance());
    }
}

public class SessionTracker implements LifecycleObserver {
    private static SessionTracker sSessionTracker;
    private static final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000;  // Time allowed for transitions

    private Timer mStopDelayTimer;
    private TimerTask mActivityTransitionTimerTask;
    private boolean mWasInBackground = true;
    private AppSession mAppSession;

    public static SessionTracker getInstance() {
        if (sSessionTracker == null) {
            sSessionTracker = new SessionTracker();
        }
        return sSessionTracker;
    }

    private SessionTracker() {
        // no-op
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onLifecycleStop() {
        submitAppSession(appSession);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onLifecycleStart() {
        mAppSession = new AppSession();
    }

    private void submitAppSession(AppSession appSession) {
        // TODO submit app session here
    }
}

public class AppSession {
    /* TODO */
}

答案 1 :(得分:6)

答案 2 :(得分:1)

好。我发布我的评论作为答案,因为提出问题的原始用户发现这确实很有用。

上述答案的问题在于,该应用程序并不想检查和解决问题。在活动关闭时结帐,而是在应用程序启动或恢复时结帐。因此,当您在应用程序打开时关闭或在活动之间移动时,这可能会出现问题,这仍然会调用oncreate()和onpause()函数。

此问题也在之前的stackoverflow上进行了讨论。以下是链接。

How to detect when an Android app goes to the background and come back to the foreground

解决此问题可能有不同的方法。以上链接提供了有关如何解决问题的更多信息。

答案 3 :(得分:1)

android.arch.lifecycle 包提供了类和接口,可让您知道应用程序在后台还是前台运行。

您的应用程序应实现LifecycleObserver接口:

public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d("MyApp", "App in foreground");
    }
}

为此,您需要将此依赖项添加到build.gradle文件中:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
}

按照Google的建议,您应尽量减少在活动的生命周期方法中执行的代码:

  

一个常见的模式是实施依赖者的行为   活动和片段的生命周期方法中的组件。   但是,这种模式导致代码的组织不善,并导致   错误的扩散。通过使用生命周期感知的组件,您可以   可以将依赖组件的代码移出生命周期方法   以及组件本身。

您可以在此处了解更多信息: https://developer.android.com/topic/libraries/architecture/lifecycle

答案 4 :(得分:0)

您可以使用oncreate()onpause()方法。