【问题标题】:Call method when home button pressed按下主页按钮时的调用方法
【发布时间】:2011-06-14 14:43:24
【问题描述】:

我的一个 Android 活动中有这个方法:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if(keyCode == KeyEvent.KEYCODE_BACK)
    {
        Log.d("Test", "Back button pressed!");
    }
    else if(keyCode == KeyEvent.KEYCODE_HOME)
    {
        Log.d("Test", "Home button pressed!");
    }
    return super.onKeyDown(keyCode, event);
}

但是,即使 KEYCODE_HOME 有效,日志方法也不会触发。这适用于后退按钮。有谁知道这是为什么以及如何让它发挥作用?

【问题讨论】:

  • @Yvette 我同意。然而,仅出于原因。无论如何,它可能应该关闭,因为经过反思,尝试和检测并不是一件好事 - 因此对于未来的 SO 访问者来说也不是一件好事。有更好的方法来停止服务(这是我真正的问题),并且您不能覆盖主页按钮,因为下面的一些答案会讨论。
  • 按照here 的建议使用 onTrimMemory()

标签: android button menu android-sdk-1.6


【解决方案1】:

Home 按钮是一个非常危险的覆盖按钮,因此,Android 不会让你覆盖它的行为,就像你使用 BACK 按钮一样。

看看这个discussion.

您会注意到主页按钮似乎是作为意图调用实现的,因此您最终必须向您的活动添加一个意图类别。然后,任何时候用户回家,你的应用都会作为一个选项出现。您应该考虑使用主页按钮要完成的任务。如果它不替换设备的默认主屏幕,我会警惕超载 HOME 按钮,但这是可能的(根据上述线程中的讨论。)

【讨论】:

  • 如果我想停止媒体播放器怎么办?如果我按 Home,它会继续播放...
  • 我不需要覆盖主页按钮,我只需要在应用消失之前停止音乐!
  • 只需检测您的活动是否进入后台。
【解决方案2】:

我花了将近一个月的时间才完成这个。刚才我解决了这个问题。 在您的活动的 onPause() 中,您必须包含以下 if 条件:

    if (this.isFinishing()){
        //Insert your finishing code here
    }

函数 isFinishing() 返回一个布尔值。如果您的应用程序实际上正在关闭,则为 True,如果您的应用程序仍在运行但例如屏幕关闭,则为 False。

希望对你有帮助!

【讨论】:

  • 代码应该是 if (!this.isFiishing()) { //home button pressed } (只需添加一个“!”)
  • iwind 的评论是正确的。更准确地说:如果按下 HOME 按钮或 TABS 按钮或 屏幕关闭isFinishing() 将是 false。 (如果按下BACK 按钮,则为true。)
【解决方案3】:

主页按钮不能被应用程序截取。这是 Android 中的设计行为。原因是为了防止恶意应用程序控制您的手机(如果用户无法按返回或主页,他可能永远无法退出应用程序)。 Home 按钮被视为用户的“安全区”,将始终启动用户配置的 Home 应用。

上述情况的唯一例外是任何配置为家庭替代的应用程序。这意味着它在其 AndroidManifest.xml 中为相关活动声明了以下内容:

<intent-filter>
   <action android:name="android.intent.action.MAIN" />
   <category android:name="android.intent.category.HOME" />
   <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

当按下主页按钮时,当前主页应用的活动onNewIntent 将被调用。

【讨论】:

  • 不起作用。 onNewIntent btw 上的文档:“对于在其包中将 launchMode 设置为“singleTop”的活动,或者如果客户端在调用 startActivity 时使用了 Intent.FLAG_ACTIVITY_SINGLE_TOP 标志,则调用此选项。在任何一种情况下,当活动重新- 在 Activity 堆栈的顶部启动,而不是正在启动的 Activity 的新实例,onNewIntent() 将在现有实例上使用用于重新启动它的 Intent 调用"
【解决方案4】:

我发现当我按下HOME按钮时,onStop()方法被调用了。你可以使用下面这段代码来监控它:

@Override
    protected void onStop() 
    {
        super.onStop();
        Log.d(tag, "MYonStop is called");
        // insert here your instructions
    }

【讨论】:

  • 它可以工作,但是当你去另一个活动时它也会被调用。因此,它不会仅在您退出应用程序时调用。
  • 说实话,这个答案是错误的。 onStop 在各种场合(如 italo 所述)被调用,不仅是在按下 Home 按钮时!
  • 当我阅读该主题时,决定使用 onStop() 覆盖来回答。这是唯一可行的方法,无需添加所有类别和其他内容。
  • 注意onStop即使在屏幕旋转时也会被调用
  • @italo 是的,这正是我的问题。你知道当用户离开我的应用程序时我应该使用什么方法让它执行吗?
【解决方案5】:

我有一个处理主页按钮按下的简单解决方案。这是我的代码,它可能很有用:

public class LifeCycleActivity extends Activity {


boolean activitySwitchFlag = false;

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if(keyCode == KeyEvent.KEYCODE_BACK)
    {
        activitySwitchFlag = true;
        // activity switch stuff..
        return true;
    }
    return false;
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

@Override 
public void onPause(){
    super.onPause();
    Log.v("TAG", "onPause" );
    if(activitySwitchFlag)
        Log.v("TAG", "activity switch");
    else
        Log.v("TAG", "home button");
    activitySwitchFlag = false;
}

public void gotoNext(View view){
    activitySwitchFlag = true;
    startActivity(new Intent(LifeCycleActivity.this, NextActivity.class));
}

}

总而言之,在活动中放置一个布尔值,当活动切换发生时(startactivity事件),设置变量并在onpause事件中检查这个变量..

【讨论】:

  • 这不是一个坏主意。虽然它实际上并没有告诉您是否按下了主页按钮,但您可以假设。我猜这个方法在电话开始响铃时调用?
【解决方案6】:

KeyEvent.KEYCODE_HOME 无法被拦截。

如果可能的话,那就太糟糕了。

(编辑):我只看到尼克斯的回答,非常完整;)

【讨论】:

    【解决方案7】:

    使用广播接收器

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // something
        // for home listen
        InnerRecevier innerReceiver = new InnerRecevier();
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        registerReceiver(innerReceiver, intentFilter);
    
    }
    
    
    
    // for home listen
    class InnerRecevier extends BroadcastReceiver {
    
        final String SYSTEM_DIALOG_REASON_KEY = "reason";
        final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
                String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                if (reason != null) {
                    if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                        // home is Pressed
                    }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案8】:

      使用onPause() 方法在主页按钮上执行您想要执行的操作。

      【讨论】:

      • onPause 也是在屏幕关闭时启动... onStop 更好。
      【解决方案9】:

      我也为 HOME 按钮苦苦挣扎了一段时间。 当用户单击 HOME 按钮时,我想停止/跳过后台服务(轮询位置)。

      这是我实施的“类黑客”解决方案;

      使用布尔值在 SharedPreferences 上保持应用的状态

      每个活动

      onResume() -> 设置 appactive=true

      onPause() -> 设置 appactive=false

      后台服务在每个循环中检查appstate,跳过动作

      如果 appactive=false

      它对我来说很好用,至少不会再耗尽电池了, 希望这会有所帮助....

      【讨论】:

      • 同样,只有当您的应用程序只有一个活动时,这才是正确的。如果您切换到同一个应用程序中的另一个活动,您将把 appActive 变量设置为 true。
      【解决方案10】:

      像这样在activity 中定义变量:

      const val SYSTEM_DIALOG_REASON_KEY = "reason"
      const val SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"
      const val SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"
      

      像这样定义你的广播接收器类:

      class ServiceActionsReceiver: BroadcastReceiver(){
              override fun onReceive(context: Context?, intent: Intent?) {
                  
                  val action = intent!!.action
                  if (action == Intent.ACTION_CLOSE_SYSTEM_DIALOGS) {
                      val reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY)
                      if (reason != null) {
                          if (reason == SYSTEM_DIALOG_REASON_HOME_KEY) {
                              //do what you want to do when home pressed
                          } else if (reason == SYSTEM_DIALOG_REASON_RECENT_APPS) {
                              //do what you want to do when recent apps pressed
                          }
                      }
                  }
              }
          }
      

      onCreate 方法或onResume 方法上注册接收器,如下所示:

      val filter = IntentFilter()
      filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
      registerReceiver(receiver, filter)
      

      像这样在清单中添加接收者:

      <receiver android:name=".ServiceActionsReceiver">
                  <intent-filter >
                      <actionandroid:name="android.intent.action.CLOSE_SYSTEM_DIALOGS"/>
                  </intent-filter>
      </receiver>
      

      【讨论】:

        猜你喜欢
        • 2016-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-01
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多