Android应用开始和结束事件

时间:2013-10-02 10:28:24

标签: android android-activity

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

我尝试了什么

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

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

有没有办法实现这样的目标。

其他:

如果我们可以了解屏幕上的应用活动是否处于活动状态,那么可以使用事件来开始或结束会话。

5 个答案:

答案 0 :(得分:5)

我可以想到两种方法:

选项1:

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

  

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

     

一旦拥有,您可以通过请求获取ComponentName对象   列表中的topActivity。

     

这是一个例子。

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: How can I get the current foreground activity (from a service)?

您可以每隔一秒钟或更短时间调用此选项来检测您的应用是否仍然有效。请注意,根据官方文档,它已被弃用,不建议用于此类事情:

  

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();
    }
}

这样,每次启动活动时,isAppRunningMyAppContext的值都为true,当您退出Activity时,它将为false但是如果另一个活动打开(例如,如果您按下后退按钮以便返回上一个活动),则该值将立即再次true

当您最终完成所有活动时,将不会调用任何onResume()方法,并且系统会调用所有onPause()方法,因此isAppRunning将为false,您知道您的Activity已不在前台。

重新开始,如果isAppRunningtrue您的应用程序在前台(开始会话跟踪),否则它已经消失(停止会话跟踪)。您可以在Timer课程中创建MyAppContext以定期检查isAppRunning的值,这样就可以了:

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

答案 1 :(得分:2)

从BaseActivity扩展您的所有活动,如下所示。这是您的最佳选择,因为只要您的活动显示或远离电话屏幕,就可以保证调用onPause和onResume方法。

class BaseActivity extends Activity {


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

    @Override
    protected void onPause() {
        super.onPause();
        // End Logging
    }
}

答案 2 :(得分:1)

您需要在Android上查看活动生命周期。

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

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

答案 3 :(得分:0)

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,那么您可以说应用已启动。 如果numOfCreated = 0,则在onActivityDestroyed中使用,然后您可以说app已关闭。

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

    registerActivityLifecycleCallbacks(new AppLifecycleTracker());

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

  3. 多数民众赞成。你很高兴。

答案 4 :(得分:0)

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

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) {
}