如何知道用户使用我的应用时是否已经过了一定的时间?

时间:2017-03-22 00:12:07

标签: android firebase firebase-analytics

如果用户在我的应用上花费至少20秒,我想向firebase发送一个事件。这看起来很简单,因为我只需要创建一个计时器。这是我到目前为止所做的:

Subscription sessionEvent = Observable.timer(20, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(aLong -> Log.v("tag", "hello"));

我在onResume内部取消订阅时订阅了我的onPause活动。 这是一个问题,因为如果我的活动开始另一个活动,也会调用onPause。这意味着即使用户仍在我的应用程序上,计时器也会停止。

我正在寻找的是当用户关闭应用时,当计时器停止时。我已经尝试使用onUserLeaveHint,不幸的是,启动另一个活动也会调用该方法。

4 个答案:

答案 0 :(得分:2)

您可以使用ActivityLifecycleCallbacks来监控应用中所有活动的状态。您可以使用Application.registerActivityLifecycleCallbacks()注册一个,并且将为每个通过其生命周期方法的Activity调用它。当您总共有0个已启动的活动时,您可以确定该用户没有查看您的应用,但他们也可以随时从任务切换器切换回来。

答案 1 :(得分:0)

如果您有多项活动,我认为没有直接的方法来检测您的应用是在前景还是后台。但是,您可以使用OnResume和OnPause来跟踪每个活动的状态。使用布尔共享首选项来跟踪每个活动的状态,并使用重复警报定期运行后台服务,以简单地检查屏幕上是否至少有活动。 StartTime-StartTime = duration。

答案 2 :(得分:0)

以下是使用Doug Stevenson的回答中提到的ActivityLifeCycleCallbacks的示例Application实现。 onTrimMemory()方法用于检测应用程序何时落后:

public class MyApplication extends Application
        implements Application.ActivityLifecycleCallbacks {

    private static final String TAG = "MyApplication";

    private Handler handler;
    private final Runnable generateEvent = new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "User engagement is 20 secs");
            // Generate analytics event
        }
    };

    private boolean mAppInForeground;

    @Override
    public void onCreate() {
        super.onCreate();

        registerActivityLifecycleCallbacks(this);
        handler = new Handler(getMainLooper());
        mAppInForeground = false;
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);

        if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
            Log.i(TAG, "onTrimMemory: App in background");
            handler.removeCallbacks(generateEvent);
            mAppInForeground = false;
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {
        // Called when any activity is started
        Log.d(TAG, "onActivityStarted: Was foreground=" + mAppInForeground);
        if (!mAppInForeground) {
            mAppInForeground = true;
            handler.postDelayed(generateEvent, 20 * 1000);
        }
    }

    // Remaining ActivityLifecycleCallbacks are not used
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
    @Override
    public void onActivityResumed(Activity activity) {}
    @Override
    public void onActivityPaused(Activity activity) {}
    @Override
    public void onActivityStopped(Activity activity) {}
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
    @Override
    public void onActivityDestroyed(Activity activity) {}
}

答案 3 :(得分:0)

我最终使用<uses-permission android:name="android.permission.GET_TASKS"/>检查应用是否在前台。这是我使用的方法:

public boolean isAppForeground(Context context) {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

    if (am == null) return false;

    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
        List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();

        if (processInfos != null && !processInfos.isEmpty()) {
            ActivityManager.RunningAppProcessInfo info = processInfos.get(0);
            if (info == null || info.processName == null || !info.processName.contentEquals(context.getPackageName()))
                return false;
        } else {
            return false;
        }
    }
    else{
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);

        if (tasks != null && !tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (topActivity == null || topActivity.getPackageName() == null || !topActivity.getPackageName().equals(context.getPackageName())) {
                return false;
            }
        } else {
            return false;
        }
    }

    return true;
}

该方法位于我的自定义Application课程中。我使用registerActivityLifecycleCallbacks检查onActivityPaused里面的应用程序是否在前台,我不会停止计时器,但如果不是,我会停止计时器。