区分按下"home"按钮和打开另一个活动



我有三个活动: - 飞溅活动 - 主要活动 - 玩家活动

当然,该应用程序从SplashActivity开始,然后启动MainActivity并关闭。MainActivity 在某个时刻启动 PlayerActivity 并进入后退堆栈。(主活动处于活动状态,但处于停止状态(然后我需要打开 MainActivity 并将 PlayerActivity 设置为后台(PlayerActivity 处于活动状态,但处于 onStop(。然后我需要再次打开玩家活动并将主活动设置为后台。

因此,当应用程序切换到另一个并返回时,PlayerActivity 和 MainActivity 通常会得到 onPause(( 和 onStop(( 而没有 onDestroy。

我需要完成所有活动并在每次用户按下"主页"按钮时启动 SplashActivity 的应用程序,但主页按钮就像在活动之间切换一样(onPause(( 和 onStop(((。所以我无法抓住杀戮活动的区别。

请帮忙。

编辑:不幸的是,onUserLeaveHint没有帮助,它是一样的。如果用户推送 HOME,则调用:

用户交互,onUserLeaveHint,暂停,停止

此活动返回上一个活动(主(,没有任何用户操作。

公共类 玩家活动扩展活动{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_next);
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            startActivity(new Intent(PlayerActivity.this, MyActivity.class));
        }
    }, 5000);
}

}

但仍然具有相同的:

用户交互,onUserLeaveHint,暂停,停止

据我所知,没有办法覆盖主页按钮或侦听主页按钮按下事件。

但是,您的目标是让应用程序知道并在发生以下情况时采取措施:

  • 您的任何活动均未显示 ->您的某个活动正在显示。

发生这种情况时,您希望显示启动对话框。

您可以跟踪用户何时在您的应用程序中,并检查用户是否从您的应用程序中导航到您的活动。

更新:您可以使用 ActivityLifecycle 回调对象来了解何时调用任何活动的生命周期回调,而不是修改以下示例所示的所有活动。你可以拿我的例子来修改它。我相信 ActivityLifecycle Callbacks.onActivityStarted(( 是在 super.onStart(( 调用之后调用的,所以在 Activity.onStart(( 中调用 super.onStart(( 之前,你必须检查 cameFromMyApplication((。这不太容易出错,并且需要更少的代码。

已修改 如何检查活动是在前景还是在可见背景中? 以适应这个问题

实现自定义应用程序类:

public class MyApplication extends Application {
  public static boolean cameFromMyApplication() {
    return count != 0;
  }  
  public static void activityStarted() {
    count++;
  }
  public static void activityStopped() {
    count--;
  }
  private static int count;
}

在 AndroidManifest 中注册您的应用程序类.xml:

<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

将onStart和onStop添加到项目中的每个活动(您可以 如果您愿意,请为您的活动创建一个共同祖先(:

@Override
protected void onStart() {
  super.onStart();
  //Do not include this check in the splash screen Activity
  if(!MyApplication.cameFromMyApplication()) {
    //User arrived from outside the application
    //Application specific code (clear Activity backstack & show splash screen in your case)
  }
  MyApplication.activityStarted();
}
@Override
protected void onStop() {
  super.onStop();
  MyApplication.activityStopped();
}

你可以这样检查它:

ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    // check if home was pressed
    if (tasks.get(0).topActivity.getPackageName().equals("com.android.launcher")) {
        // HOME button pressed
    } else {
        // RECENT APPS pressed (you can listen for the key event before)
        // activity with FLAG_ACTIVITY_NEW_TASK started
        // etc.
    }
您可以使用

可覆盖的onUserLeavesHint()功能捕获"主页按钮单击",这在您的情况下可能就足够了。

@Override
public void onUserLeaveHint() {
    super.onUserLeaveHint();
    // Do your thing
}

来自 http://developer.android.com/reference/android/app/Activity.html#onUserLeaveHint(( 的文档

受保护的无效用户离开提示 ((

当活动即将调用时作为活动生命周期的一部分调用 作为用户选择的结果进入后台。例如,当 用户按下 Home 键,将调用 onUserLeaveHint((,但 当来电导致通话中活动 自动带到前台,onUserLeaveHint(( 将不会 要求活动中断。在调用它的情况下, 此方法在活动的 onPause(( 回调之前调用。

此回调和 onUserInteraction(( 旨在帮助活动 智能管理状态栏通知;具体来说,对于 帮助活动确定取消通知的适当时间。

我一直在寻找类似问题的解决方案,上面ungalcrys提供的代码使我朝着正确的方向前进,因此这是一个更通用的问题解决方案,适合任何需要它的人

@Override
protected void onStop() {
        super.onStop();
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        // check if the app is still visible
        if (!tasks.get(0).topActivity.getPackageName().equals(getPackageName())) {
            // for some reason(HOME, BACK, RECENT APPS, etc.) the app is no longer visible
            // do your thing here
            } else {
            // app is still visible, switched to other activity
        }
    }
我知道

这个问题是前段时间问过的,但我认为这个答案可以帮助解决这个问题的任何人。

class YourApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    registerActivityLifecycleCallbacks(AppLifecycleTracker())
  }
}

class AppLifecycleTracker : Application.ActivityLifecycleCallbacks  {
  private var numStarted = 0
  override fun onActivityStarted(activity: Activity?) {
    if (numStarted == 0) {
      // app went to foreground
    }
    numStarted++
  }
  override fun onActivityStopped(activity: Activity?) {
    numStarted--
    if (numStarted == 0) {
      // app went to background
    }
  }
}

有了这个答案,您可以区分是启动了另一个活动还是按下了主页按钮(或者最近使用的应用程序按钮(,并且您可以通过实现新应用程序类中定义的接口或您喜欢的任何其他方式来调用您的活动方法。

这个答案来自谷歌I/O谈话,这里是原始答案 https://stackoverflow.com/a/42679191/14191525

最新更新