我试图写一个应用程序,做一些具体的时候,它被带回前台后一段时间。是否有一种方法可以检测应用程序是被发送到后台还是被带到前台?


当前回答

我发现了一个很好的方法来检测应用程序是否进入前台或后台。 这是我的代码。 希望这对你有帮助。

/**
 * Custom Application which can detect application state of whether it enter
 * background or enter foreground.
 *
 * @reference http://www.vardhan-justlikethat.blogspot.sg/2014/02/android-solution-to-detect-when-android.html
 */
 public abstract class StatusApplication extends Application implements ActivityLifecycleCallbacks {

public static final int STATE_UNKNOWN = 0x00;
public static final int STATE_CREATED = 0x01;
public static final int STATE_STARTED = 0x02;
public static final int STATE_RESUMED = 0x03;
public static final int STATE_PAUSED = 0x04;
public static final int STATE_STOPPED = 0x05;
public static final int STATE_DESTROYED = 0x06;

private static final int FLAG_STATE_FOREGROUND = -1;
private static final int FLAG_STATE_BACKGROUND = -2;

private int mCurrentState = STATE_UNKNOWN;
private int mStateFlag = FLAG_STATE_BACKGROUND;

@Override
public void onCreate() {
    super.onCreate();
    mCurrentState = STATE_UNKNOWN;
    registerActivityLifecycleCallbacks(this);
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    // mCurrentState = STATE_CREATED;
}

@Override
public void onActivityStarted(Activity activity) {
    if (mCurrentState == STATE_UNKNOWN || mCurrentState == STATE_STOPPED) {
        if (mStateFlag == FLAG_STATE_BACKGROUND) {
            applicationWillEnterForeground();
            mStateFlag = FLAG_STATE_FOREGROUND;
        }
    }
    mCurrentState = STATE_STARTED;

}

@Override
public void onActivityResumed(Activity activity) {
    mCurrentState = STATE_RESUMED;

}

@Override
public void onActivityPaused(Activity activity) {
    mCurrentState = STATE_PAUSED;

}

@Override
public void onActivityStopped(Activity activity) {
    mCurrentState = STATE_STOPPED;

}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

}

@Override
public void onActivityDestroyed(Activity activity) {
    mCurrentState = STATE_DESTROYED;
}

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (mCurrentState == STATE_STOPPED && level >= TRIM_MEMORY_UI_HIDDEN) {
        if (mStateFlag == FLAG_STATE_FOREGROUND) {
            applicationDidEnterBackground();
            mStateFlag = FLAG_STATE_BACKGROUND;
        }
    }else if (mCurrentState == STATE_DESTROYED && level >= TRIM_MEMORY_UI_HIDDEN) {
        if (mStateFlag == FLAG_STATE_FOREGROUND) {
            applicationDidDestroyed();
            mStateFlag = FLAG_STATE_BACKGROUND;
        }
    }
}

/**
 * The method be called when the application been destroyed. But when the
 * device screen off,this method will not invoked.
 */
protected abstract void applicationDidDestroyed();

/**
 * The method be called when the application enter background. But when the
 * device screen off,this method will not invoked.
 */
protected abstract void applicationDidEnterBackground();

/**
 * The method be called when the application enter foreground.
 */
protected abstract void applicationWillEnterForeground();

}

其他回答

你可以使用:

onRestart ()

重新开始和重新开始的区别。

正确答案

创建名为MyApp的类,如下所示:

public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

    private Context context;
    public void setContext(Context context)
    {
        this.context = context;
    }

    private boolean isInBackground = false;

    @Override
    public void onTrimMemory(final int level) {
        if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {


            isInBackground = true;
            Log.d("status = ","we are out");
        }
    }


    @Override
    public void onActivityCreated(Activity activity, Bundle bundle) {

    }

    @Override
    public void onActivityStarted(Activity activity) {

    }

    @Override
    public void onActivityResumed(Activity activity) {

        if(isInBackground){

            isInBackground = false;
            Log.d("status = ","we are in");
        }

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {

    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    }

    @Override
    public void onConfigurationChanged(Configuration configuration) {

    }

    @Override
    public void onLowMemory() {

    }
}

然后,在你想要的任何地方(最好是在应用程序中启动的第一个活动),添加下面的代码:

MyApp myApp = new MyApp();
registerComponentCallbacks(myApp);
getApplication().registerActivityLifecycleCallbacks(myApp);

完成了!现在当应用程序在后台时,我们得到日志状态:我们退出 当我们进入app,我们得到log status,我们是out

我在Github app- prospect -background-listen上创建了一个项目

为应用程序中的所有Activity创建一个BaseActivity。

public class BaseActivity extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    public static boolean isAppInFg = false;
    public static boolean isScrInFg = false;
    public static boolean isChangeScrFg = false;

    @Override
    protected void onStart() {
        if (!isAppInFg) {
            isAppInFg = true;
            isChangeScrFg = false;
            onAppStart();
        }
        else {
            isChangeScrFg = true;
        }
        isScrInFg = true;

        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();

        if (!isScrInFg || !isChangeScrFg) {
            isAppInFg = false;
            onAppPause();
        }
        isScrInFg = false;
    }

    public void onAppStart() {

        // Remove this toast
        Toast.makeText(getApplicationContext(), "App in foreground",    Toast.LENGTH_LONG).show();

        // Your code
    }

    public void onAppPause() {

        // Remove this toast
        Toast.makeText(getApplicationContext(), "App in background",  Toast.LENGTH_LONG).show();

        // Your code
    }
}

现在使用这个BaseActivity作为一个超类的所有你的活动像MainActivity扩展BaseActivity和onAppStart将被调用时,你启动你的应用程序和onappause()将被调用时,应用程序从后台从任何屏幕。

The principal problem is that you have to get an specific behavior when you start an activity from background. If you override your onPause() and onResume() methods, you'll have a close answer, but not the solution. The problem is that onPause() and onResume() methods are called even if you don't minimize your application, they can be called when you start an activity and later you press the back button to return to your activity. To eliminate that problem and to know really when your application comes from background, you must to get the running process and compare with your process:

private boolean isApplicationBroughtToBackground() {
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    if (!tasks.isEmpty()) {
        ComponentName topActivity = tasks.get(0).topActivity;
        if (!topActivity.getPackageName().equals(getPackageName())) {
            return true;
        }
    }
    return false;
}

现在你必须声明一个布尔变量:

public boolean wasPaused = false;

并询问你的活动何时进入后台:

@Override
public void onPause(){
    super.onPause();
    if(isApplicationBroughtToBackground())
        wasPaused = true;
}

现在,当你的活动再次出现在屏幕上时,在onResume()方法中询问:

@Override
public void onResume(){
    super.onResume();
    if(wasPaused){
        lockScreen(true);
    }
    wasPaused = false;
}

就是这样。现在,当您的活动进入后台,稍后用户将其带到前台时,锁定屏幕将出现。

如果你想为你的应用程序的任何活动重复这个行为,你必须创建一个活动(可以是BaseActivity),放这个方法,你所有的活动都必须从BaseActivity继承。

我希望这对你有帮助。

问候!

ActivityLifecycleCallbacks可能很有趣,但是没有很好的文档。

但是,如果您调用registerActivityLifecycleCallbacks(),您应该能够在活动被创建、销毁等时获得回调。您可以为活动调用getComponentName()。