检测应用程序是否从应用程序的“外部”启动/恢复

时间:2013-11-21 16:15:33

标签: android android-activity password-protection launch resume

我正在为一个应用程序构思一个功能,我想要一个通用的方法/方法来检测应用程序本身是从应用程序的“外部”启动还是恢复。

在这种情况下,

'外部'表示:

  • 应用程序由启动器图标
  • 启动/恢复 通过按导航栏/按键上的“app按钮”启动/恢复应用程序(如在nexus 7上)
  • app已从通知中启动/恢复
  • 应用程序已从“其他地方”启动/恢复

此功能的用例如下:

  • 该应用具有“多用户能力”,允许用户为他/她的数据创建一个或多个配置文件
  • 单个配置文件可能受pin /密码保护,以“隐藏”应用程序的其他用户的数据,或“隐藏”安装应用程序的设备的其他用户的数据
    • 如果个人资料设置了密码,当应用启动/恢复时,应用会向当前用户显示某种锁定屏幕
      • 如果输入正确,应用程序将正常显示最后一个选择配置文件的数据
      • 如果输入不正确,应用程序将以“中性”个人资料开头,或者根本没有个人资料

我在网上搜索了一些想法,并在stackoverflow上找到了相关帖子:

从我到目前为止所阅读和学到的内容来看,解决方案似乎比我想象的更复杂,并且没有开箱即用的解决方案。

我目前正在考虑基于时间标记的方法来实现此功能:

  • 将时间标志设置为受影响活动的成员变量
  • onCreate(Bundle savedInstanceState) - >在检查savedInstanceState Budle数据之前,flag被设置为'null'
    • 这检测到活动开始 - >如果设置了密码 - >显示锁定屏幕
  • onSaveInstanceState(Bundle) - >将时间标志设置为“当前时间”
  • 如果恢复onCreate(Bundle savedInstanceState),savedInstanceState将包含时间标志
    • 计算当前时间与应用最后暂停的时间之间的差异
    • 如果该差异超过某个阈值,例如30分钟 - >如果设置了密码 - >显示锁定屏幕

也许你们中的一些人已经实现了类似的东西,或者对这个问题/方法有一些意见。 我很高兴听到你的想法。

干杯

1 个答案:

答案 0 :(得分:1)

这是一个较旧的问题,但仍然相关。使用ActivityLifeCycleCallbacks有一个简单的解决方案。这个答案来自Micahel Bradshaw的blogpost。他解释了这个概念

  

关键在于了解活动如何相互协调。在活动A和B之间切换时,将按以下顺序调用其方法:

     
    

A.onPause();

         

B.onCreate();

         

B.onStart();

         

B.onResume();(活动B现在以用户为中心)

         

A.onStop();(如果屏幕上不再显示活动A)

  

解决方案:您创建了一个实现Application.ActivityLifecycleCallbacks接口的类,并保留已恢复和已停止活动的计数。

public class AppLifecycleHelper implements Application.ActivityLifecycleCallbacks {

// I use two separate variables here. You can, of course, just use one and
// increment/decrement it instead of using two and incrementing both.
private static int resumed;
private static int stopped;

    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    public void onActivityDestroyed(Activity activity) {
    }

    public void onActivityResumed(Activity activity) {
        ++resumed;
    }

    public void onActivityPaused(Activity activity) {
    }

    public void onActivitySaveInstanceState(Activity activity, Bundle     outState) {
    }

    public void onActivityStarted(Activity activity) {
        if (!isApplicationInForeground()){
            // resumed and stopped both are 0,
            // that means it is the first activity to come on display
            // i.e. App is launched from outside the app
        }
    }

    public void onActivityStopped(Activity activity) {
        ++stopped;
        if (!isApplicationInForeground()){
            // resumed and stopped both are 0
            // That means there is NO Activity in resumed state when this activity stopped
            // i.e. User came out of the App, perform all Application wide persistence tasks over here
        }
    }

    /**
     * Checks whether App is visible to the user or not
     * @return true if visible and false otherwise
     */
    public static boolean isApplicationInForeground() {
        return resumed > stopped;
    }

}

然后在你的应用程序的onCreate()中注册这个类,用于这样的Activity回调

registerActivityLifecycleCallbacks(new AppLifecycleHelper());

就是这样!无需为每个活动添加任何代码。一切都包含在AppLifecycleHelper中,只需几行代码。