从应用程序“外部"检测应用程序是否已启动/恢复 [英] Detect if an app is started/resumed from 'outside' the app
问题描述
我目前正在为应用程序设计功能,我希望有一种通用的方法/方法来检测应用程序本身是从应用程序的"外部"启动还是恢复.
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屋!
- 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
- 如果配置文件设置了密码,则在启动/恢复应用程序时,该应用程序将向当前用户显示某种锁定屏幕