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


当前回答

My app needs to "reboot" after return from background - show a series of activities, according to client solicitations. After extensive search on how to manage the background/foreground transitions (treated very differently between iOS and Android), I crossed this question. Found very useful help here, specially from the most voted answer and the one flagged as correct. However, simply reinstantiate the root activity EVERY TIME the app enters foreground looked too annoying, when you think about UX. The solution that worked for me, and the one I think's most adequated - based on the Youtube and Twitter apps functionality - was to combine the answers from @GirishNair and @d60402: Calling the timer when the app's trimming memory, as follows:

@Override
public void onTrimMemory(int level) {
    if (stateOfLifeCycle.equals("Stop")) {
        startActivityTransitionTimer();
    }

    super.onTrimMemory(level);
}

我的定时器限制设置为30秒-我正在考虑增加一点。

private final long MAX_ACTIVITY_TRANSITION_TIME = 30000;

当app进入前台,重新启动,或者app被销毁时,调用方法取消定时器。

在应用程序扩展:

@Override
public void onActivityCreated(Activity activity, Bundle arg1) {
    stopActivityTransitionTimer();
    stateOfLifeCycle = "Create";
}

@Override
public void onActivityDestroyed(Activity activity) {
    stopActivityTransitionTimer();
    stateOfLifeCycle = "Destroy";
}

在活动上(最好是在一个基础活动上,由其他活动继承):

@Override
protected void onStart() {
    super.onStart();
    if (App.wasInBackground) {
        stopActivityTransitionTimer();
    }
}

在我的情况下,当应用程序在最大时间后进入前台时,会创建一个新任务,因此stopActivityTransitionTimer()在onActivityCreated()或onActivityDestroyed()上被调用,在应用程序扩展类中-转向不必要调用活动中的方法。 希望能有所帮助。

其他回答

编辑2:我在下面写的东西实际上是行不通的。谷歌拒绝了一个包含对ActivityManager.getRunningTasks()调用的应用程序。从文档中可以明显看出,这个API仅用于调试和开发。一旦我有时间更新下面的GitHub项目,我就会更新这篇文章,使用一个使用计时器的新方案,几乎一样好。

编辑1:我已经写了一篇博客文章,并创建了一个简单的GitHub存储库,使这非常容易。

公认的和最高评价的答案都不是最好的方法。排名最高的答案是isApplicationBroughtToBackground()的实现,它不处理应用程序的主活动屈服于同一个应用程序中定义的活动,但它有不同的Java包的情况。我想到了一种方法,在这种情况下行得通。

在onPause()中调用它,它会告诉你你的应用程序是否因为另一个应用程序已经启动而进入后台,或者用户已经按下了home键。

public static boolean isApplicationBroughtToBackground(final Activity activity) {
  ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);

  // Check the top Activity against the list of Activities contained in the Application's package.
  if (!tasks.isEmpty()) {
    ComponentName topActivity = tasks.get(0).topActivity;
    try {
      PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
      for (ActivityInfo activityInfo : pi.activities) {
        if(topActivity.getClassName().equals(activityInfo.name)) {
          return false;
        }
      }
    } catch( PackageManager.NameNotFoundException e) {
      return false; // Never happens.
    }
  }
  return true;
}

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

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

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

我使用这个解决方案: http://nathanael.hevenet.com/android-dev-detecting-when-your-app-is-in-the-background-across-activities/

简而言之——构建一个专门的服务,让每个活动向他报告每个生命周期事件,这个服务获得关于应用程序状态的信息。

很像@oldschool4664的解决方案,但在我看来更干净

我在谷歌Analytics EasyTracker中使用了这个,它起作用了。可以将其扩展为使用简单整数来完成您想要的任务。

public class MainApplication extends Application {

    int isAppBackgrounded = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        appBackgroundedDetector();
    }

    private void appBackgroundedDetector() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityStarted(Activity activity) {
                EasyTracker.getInstance(MainApplication.this).activityStart(activity);
            }

            @Override
            public void onActivityResumed(Activity activity) {
                isAppBackgrounded++;
                if (isAppBackgrounded > 0) {
                    // Do something here
                }
            }

            @Override
            public void onActivityPaused(Activity activity) {
                isAppBackgrounded--;
            }

            @Override
            public void onActivityStopped(Activity activity) {
                EasyTracker.getInstance(MainApplication.this).activityStop(activity);
            }

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

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
    }
}

我的解决方案受到@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;
}