Android如何检测应用进入后台?

4
我正在尝试为我的Android应用实现一些自动注销代码。
我需要检测是否所有属于该应用程序的活动都已进入后台,而不是使用每个单独活动的onPause()onResume()。iOS有一个有用的applicationDidEnterBackground:方法,我可以利用它,但我无法在Android的Application类中找到类似的函数。
一种方法似乎是使用AtomicInteger计数器,当一个活动变得可见时,将其递增,并在完成或调用onStop()时将其递减。因此,如果计数器变为零,我可以启动一个在后台运行并处理注销的服务。这通常是如何完成的吗?
4个回答

18

没有全局回调函数,但对于每个活动,它是onStop()。 您不需要使用原子int来操纵它。 只需在每个活动中拥有一个全局int表示已启动的活动数量,在onStart()中将其增加并在onStop()中将其减少即可。


4
这很好用。如果你有一个基类来管理所有的活动,就可以轻松检测应用何时被移至前台(计数从0增加到1),何时被移至后台(计数达到0)。 - Jonathan Clément
这个答案更符合帖子的标题。如果你想检测应用程序是否进入后台,请考虑这个方法。它对我很有效。 - Keith Entzeroth
如果API > 14,可以使用registerActivityLifecycleCallbacks方法进行计数器的增加/减少。 - Mickey Tin
简单而高效。非常好。 - Niki Romagnoli

14
当“应用程序”转入后台时,您真的不希望注销用户,就像当用户切换到另一个选项卡或将浏览器窗口最小化片刻时,您不会注销Web应用程序的用户一样。如果在Web应用程序中执行这两种操作之一,您的用户将认为您的Web应用程序是一个失败的例子。同样,如果用户接到错误号码的电话或闹钟响了,他们将对您感到相当恼怒,因为他们只是在5秒前使用您的应用程序,现在必须立即返回并登录。在这里,“恼怒”指的是市场上的一星评级和恶意评论。
Web应用程序自动注销基于闲置,使用服务器会话cookie。
同样,当我构建一个安全的Android应用程序时,我将实现基于闲置的机制,可能是这样的:
步骤#1:创建一个具有静态单例实例的“Session”类。 “Session”对象保存最后访问的时间戳。
步骤#2:在每个活动的“onResume()”中查看是否存在“Session”单例。如果不存在,则它是一个全新的进程,因此如果这不是身份验证活动,则立即执行“startActivity()”以打开身份验证活动。
步骤#3:回到每个活动的“onResume()”,如果存在“Session”对象,则调用类似于“extend()”的东西。这将返回一个布尔值,“true”表示会话仍然有效(并且时间戳已更新为现在),否则为“false”。如果它返回“false”,则执行与“Session”对象为“null”相同的操作。
步骤#4:您的身份验证活动在成功时使用当前时间戳设置单例“Session”对象。
步骤#5:您的“Session”类的“extend()”方法是您确定会话是否太旧的地方。无论用户何种方式进入您的应用程序,如果会话过期(或者是全新的进程),他们将被强制进行身份验证。但是,如果用户暂时中断 - 您和/或用户可以定义“暂时” - 则无需重新进行身份验证。

糟糕,那不是我想要的。我想在<X>分钟后自动注销,而不是每次应用程序进入后台都注销。对于类似的问题,其中一个建议是在后台运行服务,并使其向所有实现广播接收器的活动发送广播,但这是更好的方法。 - Tejaswi Yerukalapudi
@Tejaswi Yerukalapudi:是的,服务和接收器方法会比较笨重。 - CommonsWare
2
有些应用程序在进入后台时注销登录是有道理的,比如银行应用程序。这只是我的个人意见... - Miguel Ribeiro
@CommonsWare 这样的说法,“当应用程序进入后台时,你真的不想注销用户”似乎有点短视和心胸狭窄。是什么让你成为开发者在特定应用程序中想要做什么的裁判? - bugfixr
在我的情况下,我需要这个功能只在应用程序被发送到后台时才能放置正在进行的通知。 - akhy
借助Web应用程序的上下文简直太棒了! - zionpi

1

我认为你的建议可能是最好的方法。不幸的是,我认为没有API调用可以检测您的应用程序是否在后台运行。您只需要操作onPause()和onResume()方法。请记住,您需要考虑活动之间的转换,因此一旦您的AtomicInteger达到0,我会等待一段时间并重新检查它是否仍然为0,以确保它不仅仅是在活动之间转换。


0
创建一个Application类,并将其包含在清单文件中。
<application
        android:name="com.example.hello.MyApplication"



public class MyApplication extends Application implements
        ActivityLifecycleCallbacks, ComponentCallbacks2 

重写以下方法。
@Override
public void onTrimMemory(int level) {
        // this method is called when the app goes in background.
        // you can perform your logout service here
        super.onTrimMemory(level);
    }

这是适用于API级别14及以上的有效内容。

您甚至可以根据应用程序在后台运行的时间来执行注销,我建议这是更好的选择。以下是创建“会话超时”的方法:

  1. onTrimMemory(int level)方法中将时间戳保存在SharedPreferences中。

  2. 在所有活动的onStart()方法中从sharedPref获取时间戳并将其与当前时间进行比较。基于此,您可以执行注销操作。

  3. 在MyApplication的onCreate()方法中清除共享首选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接