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


当前回答

我想建议你用另一种方法来做这件事。

我猜你想在程序启动时显示启动屏幕,如果它已经在后端运行,不要显示它。

您的应用程序可以连续地将当前时间写入特定的文件。 当你的应用程序正在启动时,检查最后的时间戳,如果current_time-last_time>是你指定的写入最近时间的时间范围,这意味着你的应用程序已经停止,要么是由系统杀死,要么是用户自己杀死。

其他回答

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

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

自从Android API 16以来,有一个简单的方法来检查应用程序是否在前台。这可能不是万无一失的,但Android上没有万无一失的方法。当你的服务接收到来自服务器的更新,并且必须决定是否显示通知时,这个方法就足够好了(因为如果UI是前台,用户会注意到更新而不通知)。

RunningAppProcessInfo myProcess = new RunningAppProcessInfo();
ActivityManager.getMyMemoryState(myProcess);
isInBackground = myProcess.importance != RunningAppProcessInfo.IMPORTANCE_FOREGROUND;

这篇旧文章的另一个解决方案(对那些可能有帮助的人来说):


<application android:name=".BaseApplication" ... >

public class BaseApplication extends Application {

    private class Status {
        public boolean isVisible = true;
        public boolean isFocused = true;
    }

    private Map<Activity, Status> activities;

    @Override
    public void onCreate() {
        activities = new HashMap<Activity, Status>();
        super.onCreate();
    }

    private boolean hasVisibleActivity() {
        for (Status status : activities.values())
            if (status.isVisible)
                return true;
        return false;
    }

    private boolean hasFocusedActivity() {
        for (Status status : activities.values())
            if (status.isFocused)
                return true;
        return false;
    }

    public void onActivityCreate(Activity activity, boolean isStarting) {
        if (isStarting && activities.isEmpty())
            onApplicationStart();
        activities.put(activity, new Status());
    }

    public void onActivityStart(Activity activity) {
        if (!hasVisibleActivity() && !hasFocusedActivity())
            onApplicationForeground();
        activities.get(activity).isVisible = true;
    }

    public void onActivityWindowFocusChanged(Activity activity, boolean hasFocus) {
        activities.get(activity).isFocused = hasFocus;
    }

    public void onActivityStop(Activity activity, boolean isFinishing) {
        activities.get(activity).isVisible = false;
        if (!isFinishing && !hasVisibleActivity() && !hasFocusedActivity())
            onApplicationBackground();
    }

    public void onActivityDestroy(Activity activity, boolean isFinishing) {
        activities.remove(activity);
        if(isFinishing && activities.isEmpty())
            onApplicationStop();
    }

    private void onApplicationStart() {Log.i(null, "Start");}
    private void onApplicationBackground() {Log.i(null, "Background");}
    private void onApplicationForeground() {Log.i(null, "Foreground");}
    private void onApplicationStop() {Log.i(null, "Stop");}

}

public class MyActivity extends BaseActivity {...}

public class BaseActivity extends Activity {

    private BaseApplication application;

    @Override
    protected void onCreate(Bundle state) {
        application = (BaseApplication) getApplication();
        application.onActivityCreate(this, state == null);
        super.onCreate(state);
    }

    @Override
    protected void onStart() {
        application.onActivityStart(this);
        super.onStart();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        application.onActivityWindowFocusChanged(this, hasFocus);
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    protected void onStop() {
        application.onActivityStop(this, isFinishing());
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        application.onActivityDestroy(this, isFinishing());
        super.onDestroy();
    }

}

参见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++;
    }
}

如果你想知道一个特定的活动是否在前台,如果你是一个没有直接访问应用程序的SDK,那么没有一个答案非常适合特定的情况。对我来说,我在后台线程刚刚收到一个新的聊天消息的推送通知,只想在聊天屏幕不在前台时显示系统通知。

使用ActivityLifecycleCallbacks,正如在其他答案中推荐的那样,我已经创建了一个小的util类,它包含MyActivity是否在前台的逻辑。

class MyActivityMonitor(context: Context) : Application.ActivityLifecycleCallbacks {

private var isMyActivityInForeground = false

init {
    (context.applicationContext as Application).registerActivityLifecycleCallbacks(this)
}

fun isMyActivityForeground() = isMyActivityInForeground

override fun onActivityPaused(activity: Activity?) {
    if (activity is MyActivity) {
        isMyActivityInForeground = false
    }
}

override fun onActivityResumed(activity: Activity?) {
    if (activity is MyActivity) {
        isMyActivityInForeground = true
    }
}

}