如果用户在我的应用上花费至少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
,不幸的是,启动另一个活动也会调用该方法。
答案 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
里面的应用程序是否在前台,我不会停止计时器,但如果不是,我会停止计时器。