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


当前回答

如果你打开开发人员设置“不要保留活动”-只检查创建的活动数量不够。您还必须检查isSaveInstanceState。我的自定义方法isApplicationRunning()检查android应用程序是否正在运行:

下面是我的工作代码:

public class AppLifecycleService implements Application.ActivityLifecycleCallbacks {
    private int created;
    private boolean isSaveInstanceState;
    private static AppLifecycleService instance;

    private final static String TAG = AppLifecycleService.class.getName();

    public static AppLifecycleService getInstance() {
        if (instance == null) {
            instance = new AppLifecycleService();
        }
        return instance;
    }

    public static boolean isApplicationRunning() {
        boolean isApplicationRunning = true;
        if (getCountCreatedActvities() == 0 && !isSaveInstanceState()) {
            isApplicationRunning = false;
        }
        return isApplicationRunning;
    }

    public static boolean isSaveInstanceState() {
        return AppLifecycleService.getInstance().isSaveInstanceState;
    }

    public static int getCountCreatedActvities() {
        return AppLifecycleService.getInstance().created;
    }

    private AppLifecycleService() {
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        this.isSaveInstanceState = true;
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        ++created;
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        --created;
    }

    @Override
    public void onActivityResumed(Activity activity) {   }

    @Override
    public void onActivityPaused(Activity activity) { }


    @Override
    public void onActivityStarted(Activity activity) { }

    @Override
    public void onActivityStopped(Activity activity) { }        

}

其他回答

这样怎么样:

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;
    }
}

从支持库版本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);

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

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

没有任何解决方案适合我,但我提出了一个原始的解决方案。这应该有用。如果isAppBackground返回false,那么app必须在前台。

public static boolean isAppBackground(Context context){
        boolean isBackground=true;
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH){
            List<ActivityManager.RunningAppProcessInfo> runningProcesses =activityManager.getRunningAppProcesses();
            for(ActivityManager.RunningAppProcessInfo processInfo:runningProcesses){
                if(processInfo.importance==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
                    for(String activeProcess:processInfo.pkgList){
                        if(activeProcess.equals(context.getPackageName())){
                            isBackground = false;
                        }
                    }
                }
            }
        }else{
            List<ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
            if(taskInfo.size()>0) {
                ComponentName componentName = taskInfo.get(0).topActivity;
                if(componentName.getPackageName().equals(context.getPackageName())){
                    isBackground = false;
                }
            }
        }
        return isBackground;
    }

官方文件:

系统区分前台和后台应用程序。(用于服务限制的后台定义与内存管理使用的定义不同;一个应用程序可能在后台的内存管理,但在前台的能力,启动服务。)一个应用程序被认为是在前台,如果以下任何一个是真的:

它有一个可见的活动,无论该活动是启动还是暂停。 它有一个前台服务。 另一个前台应用通过绑定到它的一个服务或使用它的一个内容提供者来连接到该应用。例如,如果另一个应用绑定到它的: 输入法设置 壁纸服务 通知侦听器 语音或文字服务

如果这些条件都不为真,应用程序被认为是在后台。