如何知道用户使用我的应用程序时是否已经过了一定时间?
How to know if a certain amount of time has passed while user is using my app?
如果用户在我的应用上花费至少 20 秒,我想向 firebase 发送一个事件。这看起来很简单,因为我只需要创建一个计时器。这是我到目前为止所做的:
Subscription sessionEvent = Observable.timer(20, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> Log.v("tag", "hello"));
我在 activity 的 onResume
中订阅,而在 onPause
中取消订阅。
然而,这是一个问题,因为如果我的 activity 启动另一个 activity,onPause
也会被调用。这意味着即使用户仍在我的应用程序上,计时器也会停止。
我要查找的是用户关闭应用程序的时间,即计时器停止的时间。我已经尝试使用 onUserLeaveHint
,不幸的是,启动另一个 activity 也会调用该方法。
如果您有多个活动,我认为没有直接的方法可以检测您的应用程序是在前台还是后台。但是,您可以使用 OnResume 和 OnPause 来跟踪每个 activity 的状态。使用布尔共享首选项跟踪每个 activity 的状态,并定期 运行 使用重复警报的后台服务来简单地检查屏幕上是否至少有 activity。 StartTime-StartTime = duration.
您可以使用 ActivityLifecycleCallbacks to monitor the state of all activities in your app. You can register one with Application.registerActivityLifecycleCallbacks(),它会在每个 Activity 经历其生命周期方法时被调用。当您启动的活动总数为 0 时,您可以确定用户没有在查看您的应用,但他们也完全有可能随时从任务切换器切换回来。
下面是一个示例Application implementation that uses the ActivityLifeCycleCallbacks
mentioned in Doug Stevenson's answer. The 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) {}
}
我最后使用 <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
class 中。我使用 registerActivityLifecycleCallbacks
检查 onActivityPaused
如果应用程序在前台,我不会停止计时器,但如果不是,我会停止计时器。
如果用户在我的应用上花费至少 20 秒,我想向 firebase 发送一个事件。这看起来很简单,因为我只需要创建一个计时器。这是我到目前为止所做的:
Subscription sessionEvent = Observable.timer(20, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> Log.v("tag", "hello"));
我在 activity 的 onResume
中订阅,而在 onPause
中取消订阅。
然而,这是一个问题,因为如果我的 activity 启动另一个 activity,onPause
也会被调用。这意味着即使用户仍在我的应用程序上,计时器也会停止。
我要查找的是用户关闭应用程序的时间,即计时器停止的时间。我已经尝试使用 onUserLeaveHint
,不幸的是,启动另一个 activity 也会调用该方法。
如果您有多个活动,我认为没有直接的方法可以检测您的应用程序是在前台还是后台。但是,您可以使用 OnResume 和 OnPause 来跟踪每个 activity 的状态。使用布尔共享首选项跟踪每个 activity 的状态,并定期 运行 使用重复警报的后台服务来简单地检查屏幕上是否至少有 activity。 StartTime-StartTime = duration.
您可以使用 ActivityLifecycleCallbacks to monitor the state of all activities in your app. You can register one with Application.registerActivityLifecycleCallbacks(),它会在每个 Activity 经历其生命周期方法时被调用。当您启动的活动总数为 0 时,您可以确定用户没有在查看您的应用,但他们也完全有可能随时从任务切换器切换回来。
下面是一个示例Application implementation that uses the ActivityLifeCycleCallbacks
mentioned in Doug Stevenson's answer. The 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) {}
}
我最后使用 <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
class 中。我使用 registerActivityLifecycleCallbacks
检查 onActivityPaused
如果应用程序在前台,我不会停止计时器,但如果不是,我会停止计时器。