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


当前回答

这样怎么样:

boolean isBackgrounded() {
    try {
        context.startService(new Intent(action));
        return false;
    }
    catch (IllegalStateException exc) {
        // "Not allowed to start service Intent: app is in background"
        return true;
    }
}

其他回答

参见onActivityDestroyed函数中的注释。

适用于SDK目标版本14>:

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;

public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks {

    public static int active = 0;

    @Override
    public void onActivityStopped(Activity activity) {
        Log.i("Tracking Activity Stopped", activity.getLocalClassName());
        active--;
    }

    @Override
    public void onActivityStarted(Activity activity) {
        Log.i("Tracking Activity Started", activity.getLocalClassName());
        active++;
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
    }

    @Override
    public void onActivityResumed(Activity activity) {
        Log.i("Tracking Activity Resumed", activity.getLocalClassName());
        active++;
    }

    @Override
    public void onActivityPaused(Activity activity) {
        Log.i("Tracking Activity Paused", activity.getLocalClassName());
        active--;
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
        active--;

        // if active var here ever becomes zero, the app is closed or in background
        if(active == 0){
            ...
        }

    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        Log.i("Tracking Activity Created", activity.getLocalClassName());
        active++;
    }
}

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

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

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

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

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

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

我只是用我的方法介绍我的解决方案。 我通过在我的应用程序中的每个活动的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;
}

另一种没有额外依赖的方法是:

只需将此方法添加到应用程序类中,并在onCreate()中调用它即可。

var isInBackground = true

private fun setupActivityLifecycleCallbacks() {
    registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
        override fun onActivityStarted(activity: Activity) {}
        override fun onActivityResumed(activity: Activity) {
            isInBackground = false
        }
        override fun onActivityPaused(activity: Activity) {
            isInBackground = true
        }
        override fun onActivityStopped(activity: Activity) {}
        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
        override fun onActivityDestroyed(activity: Activity) {}
    })
}

AFAIK,你甚至可以使isInBackground静态,这样你就可以在没有上下文的情况下使用伴生对象访问它

您应该使用共享首选项来存储属性,并使用来自活动的服务绑定对其进行操作。如果你只使用绑定(也就是从不使用startService),那么你的服务将只在你绑定它时运行,(绑定onResume和取消绑定onPause),这将使它只在前台运行,如果你确实想在后台工作,你可以使用常规的启动停止服务。