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


当前回答

使用ProcessLifecycleOwner在Activity(或任何类)中从后台到前台检测app的示例。 当应用程序启动时,我缓存启动时间,然后在每个活动中,我将检查应用程序时间,以知道活动是否在第一时间启动或从后台启动

class MyApplication : Application(), LifecycleObserver {

    var appStartBeginTime: Long? = null

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onMoveToForeground() {
        Log.i("TAG", "onMoveToForeground")
        appStartBeginTime = System.currentTimeMillis()
    }
}

LoginActivity

class LoginActivity : AppCompatActivity() {
    var localAppStartBeginTime: Long? = null

    ...
    
    // Detect in onResume() instead of onStart because 
    // onMoveToForeground() in MyApplication will fired before onStart 
    override fun onResume() {
        super.onResume()
        if (isOpenedFirstTimeOrFromBackground()) {
            Log.i("TAG", "open first time or from background")

            // do something: eg, call API
        } else {
            Log.i("TAG", "on in another time")
        }
    }

    private fun isOpenedFirstTimeOrFromBackground(): Boolean {
        val globalStartBeginTime = (application as MyApplication).appStartBeginTime
        if (localAppStartBeginTime != globalStartBeginTime) {
            localAppStartBeginTime = globalStartBeginTime
            return true
        }
        return false
    }
}

安卓清单

<manifest ...>

    <application
        android:name=".MyApplication"
        ...>
            
    </application>

</manifest>

演示 https://github.com/PhanVanLinh/AndroidDetectAppFromBackgroundToForeground

其他回答

我知道有点晚了,但我认为所有这些答案都有一些问题,而我这样做了,这是完美的。

创建一个活动生命周期回调,如下所示:

 class ActivityLifeCycle implements ActivityLifecycleCallbacks{

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

    }

    @Override
    public void onActivityStarted(Activity activity) {

    }

    Activity lastActivity;
    @Override
    public void onActivityResumed(Activity activity) {
        //if (null == lastActivity || (activity != null && activity == lastActivity)) //use this condition instead if you want to be informed also when  app has been killed or started for the first time
        if (activity != null && activity == lastActivity) 
        {
            Toast.makeText(MyApp.this, "NOW!", Toast.LENGTH_LONG).show();
        }

        lastActivity = activity;
    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {

    }

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

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    }
}

然后像下面这样在你的应用类上注册它:

public class MyApp extends Application {

@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(new ActivityLifeCycle());
}

我的解决方案受到@d60402的答案的启发,也依赖于一个时间窗口,但不使用定时器:

public abstract class BaseActivity extends ActionBarActivity {

  protected boolean wasInBackground = false;

  @Override
  protected void onStart() {
    super.onStart();
    wasInBackground = getApp().isInBackground;
    getApp().isInBackground = false;
    getApp().lastForegroundTransition = System.currentTimeMillis();
  }

  @Override
  protected void onStop() {
    super.onStop();
    if( 1500 < System.currentTimeMillis() - getApp().lastForegroundTransition )
      getApp().isInBackground = true;
  }

  protected SingletonApplication getApp(){
    return (SingletonApplication)getApplication();
  }
}

其中SingletonApplication是Application类的扩展:

public class SingletonApplication extends Application {
  public boolean isInBackground = false;
  public long lastForegroundTransition = 0;
}

这些答案似乎不正确。当另一个活动开始和结束时,也会调用这些方法。你能做的是保留一个全局标志(是的,全局不好:),并在每次启动一个新活动时将其设置为true。在每个活动的onCreate中将其设置为false。然后,在onPause中检查这个标志。如果为假,你的应用就会进入后台,或者被杀死。

2021年11月更新

实际设置如下

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleListener())
    }
}

class AppLifecycleListener : DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) { // app moved to foreground
    }

    override fun onStop(owner: LifecycleOwner) { // app moved to background
    }
}

依赖关系

implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common:$lifecycle_version"

原来的答案

ProcessLifecycleOwner似乎也是一个很有前途的解决方案。

ProcessLifecycleOwner将分派ON_START, ON_RESUME事件,当第一个活动通过这些事件时。ON_PAUSE, ON_STOP,事件将在最后一个活动通过它们后延迟分派。这个延迟足够长,可以保证ProcessLifecycleOwner在由于配置更改而销毁和重新创建活动时不会发送任何事件。

实现可以简单到

class AppLifecycleListener : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onMoveToForeground() { // app moved to foreground
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onMoveToBackground() { // app moved to background
    }
}

// register observer
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleListener())

根据源代码,当前延迟值为700ms。

使用此特性还需要依赖项:

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion"

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