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


当前回答

我们用这个方法。它看起来太简单了,但它在我们的应用程序中经过了良好的测试,实际上在所有情况下都运行得非常好,包括通过“home”按钮进入主屏幕,通过“返回”按钮,或在屏幕锁定后返回主屏幕。试一试。

想法是,当在前景,Android总是开始新的活动之前停止前一个。这并不能保证,但这就是它的工作原理。顺便说一句,Flurry似乎使用了同样的逻辑(只是猜测,我没有检查,但它在相同的事件中挂钩)。

public abstract class BaseActivity extends Activity {

    private static int sessionDepth = 0;

    @Override
    protected void onStart() {
        super.onStart();       
        sessionDepth++;
        if(sessionDepth == 1){
        //app came to foreground;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (sessionDepth > 0)
            sessionDepth--;
        if (sessionDepth == 0) {
            // app went to background
        }
    }

}

编辑:根据注释,我们也移动到onStart()在以后的版本的代码。此外,我还添加了超级调用,这是我最初的文章中所没有的,因为这更像是一个概念,而不是一个工作代码。

其他回答

我所做的是确保所有应用程序内的活动启动startActivityForResult,然后检查onActivityResult是否在onResume之前被调用。如果不是,这意味着我们刚刚从应用程序之外的某个地方返回。

boolean onActivityResultCalledBeforeOnResume;

@Override
public void startActivity(Intent intent) {
    startActivityForResult(intent, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    onActivityResultCalledBeforeOnResume = true;
}

@Override
protected void onResume() {
    super.onResume();
    if (!onActivityResultCalledBeforeOnResume) {
        // here, app was brought to foreground
    }
    onActivityResultCalledBeforeOnResume = false;
}

这是@d60402回答的修改版本:https://stackoverflow.com/a/15573121/4747587

按照上面提到的去做。但是,与其有一个Base Activity,并将其作为每个活动的父活动,并重写onResume()和onPause,不如执行以下操作:

在你的应用程序类中,添加这样一行:

registerActivityLifecycleCallbacks(应用程序。ActivityLifecycleCallbacks回调);

这个回调有所有的活动生命周期方法,你现在可以覆盖onactivityresume()和onActivityPaused()。

看看这个Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b

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继承。

我希望这对你有帮助。

问候!

我设法监控应用导航到后台和回前台通过实现一个BaseActivity,利用onResume, onPause和onStop活动回调的使用。这是我的实现。

override fun onResume() {
    super.onResume()
    if (AppActivityState.state == AppState.ON_LAUNCHED) {
        // We are in the first launch.
        onLaunched()
    } else {
        if (AppActivityState.state == AppState.ON_BACKGROUND) {
            // We came from background to foreground.
            AppActivityState.state = AppState.ON_FOREGROUND
            onForeground()
        } else {
            // We are just navigating through pages.
            AppActivityState.state = AppState.RESUMED
        }
    }
}

override fun onPause() {
    super.onPause()
    // If state is followed by onStop then it means we will going to background.
    AppActivityState.state = AppState.PAUSED
}

override fun onStop() {
    super.onStop()

    // App will go to background base on the 'pause' cue.
    if (AppActivityState.state == AppState.PAUSED) {
        AppActivityState.state = AppState.ON_BACKGROUND
        onBackground()
    }
}

在创建BaseActivity之后,你只需要将这个activity扩展到应用程序中的任何activity。

在这些类型的实现中,您可以准确地检测到以下内容: onBackground >应用程序将进入后台 onForeground >应用将返回前台 onLaunch >应用程序刚刚打开

我希望这对你有帮助:)

lifecycle包提供了类和接口,让您可以构建生命周期感知的组件

您的应用程序应该实现LifecycleObserver接口:

public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d("MyApp", "App in foreground");
    }
}

为此,您需要将此依赖项添加到构建中。gradle文件:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
}

正如谷歌所建议的,你应该最小化在activity的生命周期方法中执行的代码:

一种常见的模式是实现依赖的操作 活动和片段的生命周期方法中的组件。 然而,这种模式会导致代码组织不佳,并且导致 错误的扩散。通过使用生命周期感知组件,您 是否可以将依赖组件的代码移出生命周期方法 以及组件本身。

你可以在这里阅读更多: https://developer.android.com/topic/libraries/architecture/lifecycle