所谓后台,我的意思是应用程序的活动目前对用户都不可见?


当前回答

现在回答可能已经太迟了,但如果有人来访,我建议有一个解决方案, 一个应用程序想要知道它的状态是在后台还是在前台的原因可以有很多,有几个是, 1. 当用户在BG时显示祝酒和通知。 2.第一次从BG来的用户执行一些任务,如投票,重画等。

Idolon和其他人的解决方案解决了第一部分,但没有解决第二部分。如果你的应用程序中有多个活动,并且用户在它们之间切换,那么当你处于第二个活动时,可见标志将为假。所以它不能被确定地使用。

我做了一些CommonsWare建议的事情,“如果服务确定没有可见的活动,并且在一段时间内保持这种状态,那么在下一个逻辑停止点停止数据传输。”

粗体部分很重要,可以用来完成第二项。所以我所做的是一旦我得到onActivityPaused(),不改变可见直接为假,而是有一个3秒的定时器(这是下一个活动应该启动的最大值),如果没有onactivityresume()调用在接下来的3秒,改变可见为假。 类似地,在onactivityresume()如果有一个定时器,然后我取消它。 总之,可见变成了isAppInBackground。

对不起,不能复制粘贴代码…

其他回答

我建议你仔细阅读这个页面:http://developer.android.com/reference/android/app/Activity.html

简而言之,你的活动在onStop()被调用后不再可见。

除非你自己跟踪它,否则无法确定你的任何活动是否可见。也许你应该考虑问一个新的StackOverflow问题,解释一下你想从用户体验中获得什么,这样我们也许可以给你其他的实现想法。

我认为这个问题应该更清楚。什么时候?在哪里?你想知道应用是否处于后台的具体情况是什么?

我只是用我的方法介绍我的解决方案。 我通过在我的应用程序中的每个活动的onStop方法中使用RunningAppProcessInfo类的字段“重要性”来完成这一点,这可以简单地通过为其他活动提供一个BaseActivity来扩展,实现onStop方法来检查“重要性”的值。代码如下:

public static boolean isAppRunning(Context context) {
    ActivityManager activityManager = (ActivityManager) context
        .getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningAppProcessInfo> appProcesses = activityManager
        .getRunningAppProcesses();
    for (RunningAppProcessInfo appProcess : appProcesses) {
        if (appProcess.processName.equals(context.getPackageName())) {
            if (appProcess.importance != RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE) {
                return true;
            } 
        }
    }
    return false;
}

从支持库版本26开始,你可以使用ProcessLifecycleOwner,就像这里描述的那样将它添加到你的依赖项中,例如:

dependencies {
    def lifecycle_version = "1.1.1"

    // ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData).
    //     Support library depends on this lightweight import
    implementation "android.arch.lifecycle:runtime:$lifecycle_version"
    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // use kapt for Kotlin
}

然后只要查询ProcessLifecycleOwner当你想要应用程序状态时,例子:

// Check if app is in background
ProcessLifecycleOwner.get().getLifecycle().getCurrentState() == Lifecycle.State.CREATED;

// Check if app is in foreground
ProcessLifecycleOwner.get().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);

这段代码将在任何情况下检查前台和后台:

Java代码:

private static boolean isApplicationForeground(Context context) {
    KeyguardManager keyguardManager =
            (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);

    if (keyguardManager.isKeyguardLocked()) {
        return false;
    }
    int myPid = Process.myPid();

    ActivityManager activityManager =
            (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

    List<ActivityManager.RunningAppProcessInfo> list;

    if ((list = activityManager.getRunningAppProcesses()) != null) {
        for (ActivityManager.RunningAppProcessInfo aList : list) {
            ActivityManager.RunningAppProcessInfo info;
            if ((info = aList).pid == myPid) {
                return info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
            }
        }
    }
    return false;
}

芬兰湾的科特林代码:

private fun isApplicationForeground(context: Context): Boolean {
        val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        if (keyguardManager.isKeyguardLocked) {
            return false
        }
        val myPid = Process.myPid()
        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        var list: List<ActivityManager.RunningAppProcessInfo>
        if (activityManager.runningAppProcesses.also { list = it } != null) {
            for (aList in list) {
                var info: ActivityManager.RunningAppProcessInfo
                if (aList.also { info = it }.pid == myPid) {
                    return info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                }
            }
        }
        return false
    }