从应用程序“外部"检测应用程序是否已启动/恢复 [英] Detect if an app is started/resumed from 'outside' the app

查看:145
本文介绍了从应用程序“外部"检测应用程序是否已启动/恢复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为应用程序设计功能,我希望有一种通用的方法/方法来检测应用程序本身是从应用程序的"外部"启动还是恢复.

I'm currently concepting a feature for an app, where I'd like a general method/approach to detect if the app itself was started or resumed from 'outside' the app.

'外部'表示:

  • 应用已通过启动器图标启动/恢复
  • 通过按导航栏/键中的应用程序按钮"来启动/恢复应用程序(例如在nexus 7上)
  • 应用已从通知启动/恢复
  • 应用已从其他地方"启动/恢复
  • app was started/resumed by the launcher icon
  • app was started/resumed by pressing the 'app button' from a navigation bar/key (like on a nexus 7)
  • app was started/resumed from a notification
  • app was started/resumed from 'somewhere else'

此功能的用例如下:

  • 该应用程序具有多用户功能",可让用户为其数据创建一个或多个配置文件
  • 单个配置文件可能受到密码/密码保护,以隐藏"来自该应用程序其他用户的数据,或隐藏"来自该应用程序安装设备的其他用户的数据
    • 如果配置文件设置了密码,则在启动/恢复应用程序时,该应用程序将向当前用户显示某种锁定屏幕
      • 如果输入正确,则该应用将正常启动,显示上一次选择的配置文件的数据
      • 如果输入错误,则该应用程序将以中性"配置文件开头或根本没有配置文件
      • The app has a 'multi-user-ability' that allows the user(s) to create one ore more profiles for his/her data
      • A single profile may be pin/password protected to 'hide' the data from other user(s) of the app, or 'hide' data from other user(s) of the device where the app is installed
        • If a profile has a password set, the app will show some kind of a lock screen to the current user when the app is started/resumed
          • If entered correctly, the app will start normally showing the data of the last select profile
          • If entered incorrectly, the app will start with a 'neutral' profile or no profile at all

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

          I've searched the web for ideas, and found relevant posts on stackoverflow only:

          • Is there any way to distinguish between an Android Activity onResume from the home screen?
          • Android - detecting application launch from home or history
          • Determine if app was launched from home screen?

          到目前为止,我已经阅读和学习到的是,一个解决方案似乎比我想象的要复杂,并且没有开箱即用的解决方案.

          From what I've read and learned so far is, that a solution seems to be more complex than I've thought and that there's no out of the box solution for this.

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

          I'm currently thinking about a time-flag based approach to implement this feature:

          • 将时间标记设置为受影响活动的成员变量
          • onCreate(Bundle savedInstanceState)->标志设置为"null",然后检查saveInstanceState Budle中的数据
            • 这将检测到活动开始->如果设置了密码->显示锁定屏幕
            • set a time flag as a member variable of an affected activity
            • onCreate(Bundle savedInstanceState) --> flag is set to 'null' before checking the savedInstanceState Budle for data
              • this detects an activity start --> if password is set --> show the lock screen
              • 计算当前时间与上一次暂停应用之间的时间差
              • 如果此差异高于某个阈值,例如30分钟->以及是否设置了密码->显示锁定屏幕

              也许你们中的一些人已经实施了类似的措施,或者对此事/方法有一些投入. 我很高兴听到您的想法.

              Maybe some of you have already implemented something similiar or do have some input to this matter/approach. I'd be glad to hear your ideas.

              欢呼

              推荐答案

              这是一个较旧的问题,但仍很重要.使用ActivityLifeCycleCallbacks有一个简单的解决方案.此答案来自Micahel的博客布拉德肖.他解释了这个概念

              It's an older question but still relevant. There is a simple solution using ActivityLifeCycleCallbacks. This answer is derived from this blogpost by Micahel Bradshaw. He explains the concept

              关键在于了解活动之间如何协调.在活动A和活动B之间切换时,它们的方法按以下顺序调用:

              The key is in understanding how activities coordinate with each other. When switching between activities A and B, their methods are called in this order:

              A.onPause();

              B.onCreate();

              B.onStart();

              B.onResume();(活动B现在具有用户焦点)

              B.onResume(); (Activity B now has user focus)

              A.onStop();(如果活动A在屏幕上不再可见)

              A.onStop(); (if Activity A is no longer visible on screen)

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

              Solution: You create a class which implements Application.ActivityLifecycleCallbacks interface and keep count of resumed and stopped activities.

              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回调注册此类

              And then in your Application's onCreate() register this class for Activity callbacks like this

              registerActivityLifecycleCallbacks(new AppLifecycleHelper());

              就是这样!无需向每个活动添加任何代码.只需几行代码,所有内容都包含在AppLifecycleHelper中.

              and that's it! No need to add any code to every activity. Everything is contained in AppLifecycleHelper with just a few lines of code.

              这篇关于从应用程序“外部"检测应用程序是否已启动/恢复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆