11

我有一个应用程序可以跟踪用户在应用程序上的活动,包括时间等,现在如果用户打开了应用程序,它将开始一个会话,直到用户在这个应用程序中,他的会话将继续,他可以切换到多个活动。现在同时他切换到另一个应用程序,他的会话记录应该被停止并写入文件

我试过的

我创建了一个基本活动,如果计数器为零,则在恢复事件时,我开始会话并递增计数器,在停止事件时,我递减计数器,如果计数器为零,我停止会话

但这不会计算跟踪的实际问题,因为当用户切换到另一个应用程序时,android 不会停止活动。

那么有没有办法实现这样的事情。

额外的:

如果我们可以获取应用程序活动是否在屏幕上处于活动状态,则可以使用事件来开始或结束会话。

4

6 回答 6

6

我可以想到两种方法:

选项1:

您可以创建一个服务,在前台扫描当前应用程序并查看它是否是您的活动。这是您可以使用的一些代码,我从另一个答案中获取:

有一种从 ActivityManager 服务获取正在运行的任务列表的简单方法。您可以请求在手机上运行的最大任务数,默认情况下,首先返回当前活动的任务。

topActivity一旦你有了它,你可以通过从你的列表中请求来获得一个 ComponentName 对象。

这是一个例子。

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);

     // get the info from the currently running task
     List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1); 

     Log.d("topActivity", "CURRENT Activity ::"
             + taskInfo.get(0).topActivity.getClassName());

     ComponentName componentInfo = taskInfo.get(0).topActivity;
   componentInfo.getPackageName();

您的清单需要以下权限:

<uses-permission android:name="android.permission.GET_TASKS"/>

链接到答案:Android:如何获取当前的前台活动(来自服务)?

您可以每隔一秒或更短的时间调用一次,以检测您的应用是否仍处于活动状态。请注意,根据官方文档,它已被弃用,不建议用于此类事情:

getRunningTasks()

注意:此方法仅用于调试和呈现任务管理用户界面。这绝不应该用于应用程序中的核心逻辑,例如根据此处找到的信息来决定不同的行为。此类用途不受支持,将来可能会中断。例如,如果多个应用程序可以同时主动运行,则出于控制流的目的对此处数据的含义所做的假设将是不正确的。


选项 2:

第二个选项是创建一个Application带有标志的类,例如isAppRunning,根据您的应用程序是否在前台,该标志将是 true 或 false:

public class MyAppContext extends Application {

   public boolean isAppRunning = true;

   public void setIsAppRunning(boolean v){
      isAppRunning = v;
   }

   public boolean isAppRunning(){
      return isAppRunning;
   }

}

然后AndroidManifest.xml你必须添加这个类,以便在你的应用程序启动时使用它。只需android:name=".MyAppContext"在应用程序标签下添加:

<application
        android:name=".MyAppContext"

现在,在您拥有的每个活动中,您应该覆盖onResume()并将onPause()标志设置为相应的值:

class BaseActivity extends Activity {


    @Override
    protected void onResume() {
        super.onResume();
        ((MyAppContext)getApplication()).setIsAppRunning(true);
    }

    @Override
    protected void onPause() {
        ((MyAppContext)getApplication()).setIsAppRunning(false);
        super.onPause();
    }
}

这样,每次启动 Activity 时,inisAppRunning的值MyAppContext将是立即再次。trueActivityfalsetrue

当您最终完成所有活动时,将不会调用任何方法,并且将onResume()调用所有onPause()方法,并且您知道您不再处于前台。isAppRunningfalseActivity

所以恢复,如果isAppRunningtrue的应用程序在前台(启动会话跟踪),否则它就消失了(停止会话跟踪)。您可以创建一个TimerMyAppContextisAppRunning定期检查 的值,因此它将是:

public class MyAppContext extends Application {

   public boolean isAppRunning = true;
   public final int timerRate = 500;    // Execute timer task every 500mS

   public void setIsAppRunning(boolean v){
      isAppRunning = v;
   }

   public boolean isAppRunning(){
      return isAppRunning;
   }

   @Override
   public void onCreate() {
      super.onCreate();
      Timer mTimer = new Timer();

      mTimer.scheduleAtFixedRate(new TimerTask() {
         @Override
         public void run() {
            if(isAppRunning) startSesionTracking();
            else stopSesionTracking();
         }
      }, 0, REFRESH_TIME);
   }

   private void startSesionTracking () { ... };
   private void stopSesionTracking () { ... };

}

您应该timerRate根据您希望在会话跟踪中获得的精度进行修改。

于 2013-10-02T11:33:59.930 回答
2

从 BaseActivity 扩展您的所有活动,如下所示。这是您的最佳选择,因为当您的活动出现或离开手机屏幕时,保证会调用 onPause 和 onResume 方法。

class BaseActivity extends Activity {


    @Override
    protected void onResume() {
        super.onResume();
        // Start Logging
    }

    @Override
    protected void onPause() {
        super.onPause();
        // End Logging
    }
}
于 2013-10-02T12:30:13.103 回答
2

1.创建一个名为 AppLifecycleTracker 的类并将其粘贴。

private class AppLifecycleTracker implements ActivityLifecycleCallbacks {
            private int numStarted = 0;
            private String TAG = "AppLifecycleTracker";


            private int numOfCreated = 0;

            @Override`enter code here`
            public void onActivityCreated(Activity activity, Bundle bundle) {
                if (numOfCreated == 0) {
                    Log.d(TAG, "onActivityCreated: app started");
                }
                numOfCreated++;
                Log.d(TAG, "onActivityCreated: " + numOfCreated);
            }

            @Override
            public void onActivityStarted(Activity activity) {
                if (numStarted == 0) {
                    // app went to foreground
                    Log.d(TAG, "onActivityStarted: foreground");

                }
                numStarted++;


            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                numStarted--;
                if (numStarted == 0) {
                    // app went to background
                    Log.d(TAG, "onActivityStarted: background");

                }
            }

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

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                numOfCreated--;
                Log.d(TAG, "onActivityDestroyed: " + numOfCreated);
            }
        }

* 在 onActivityCreate 中如果 numOfCreated = 0,那么你可以说应用程序已经启动。*在 onActivityDestroyed 中,如果 numOfCreated = 0,则可以说应用已关闭。

  1. 创建一个扩展Application的类,在onCreate中添加这一行

    registerActivityLifecycleCallbacks(new AppLifecycleTracker());

  2. 在 manifest.xml 中将应用程序名称设置为 Application 类

而已。你已准备好出发。

于 2017-12-17T03:32:10.087 回答
1

您需要查看 Android 上的 Activity 生命周期。

您需要的是onPause- 请参阅此处的文档

我还要提到,即使在多个活动之间切换时也会触发 onPause,因此您需要跟踪它何时暂停以转到另一个屏幕。

于 2013-10-02T10:31:42.870 回答
0

您可以通过我提到的下面的源代码轻松做到这一点,该源代码也是从方向更改中保存的。(参考

public class ApplicationEventTracker implements Application.ActivityLifecycleCallbacks {
private int activityReferences = 0;
private boolean isActivityChangingConfigurations = false;

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

@Override
public void onActivityStarted(Activity activity) {
    if (++activityReferences == 1 && !isActivityChangingConfigurations) {
        // App enters foreground
    }
}

@Override
public void onActivityResumed(Activity activity) {
}

@Override
public void onActivityPaused(Activity activity) {
}

@Override
public void onActivityStopped(Activity activity) {
    isActivityChangingConfigurations = activity.isChangingConfigurations();
    if (--activityReferences == 0 && !isActivityChangingConfigurations) {
        // App enters background
    }
}

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

@Override
public void onActivityDestroyed(Activity activity) {
}
于 2019-10-24T17:19:15.043 回答
0

现在 Android 提供生命周期观察者。所以你可以使用它。您可以在应用程序类中添加观察者来检测应用程序的状态。您可以在此链接中找到更多详细信息什么是生命周期观察者以及如何正确使用它?

public class MyApplication extends MultiDexApplication implements LifecycleObserver
        
        @Override
        public void onCreate() {
            super.onCreate();
        
            ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
        
        }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void appInResumeState() {
        Toast.makeText(this,"In Foreground",Toast.LENGTH_LONG).show();
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void appInPauseState() {
        Toast.makeText(this,"In Background",Toast.LENGTH_LONG).show();
    }
}
于 2021-08-18T07:02:42.903 回答