按下主页按钮时的呼叫方法

时间:2011-01-24 15:51:08

标签: android button menu android-sdk-1.6

我的一个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有效,log方法也不会触发。这适用于后退按钮。有谁知道这是为什么以及如何让它发挥作用?

10 个答案:

答案 0 :(得分:31)

“主页”按钮是一个非常危险的按钮,因此,Android不会让您像使用“返回”按钮一样覆盖其行为。

看看这个discussion.

您会注意到主页按钮似乎是作为意图调用实现的,因此您最终必须为您的活动添加意图类别。然后,只要用户回家,您的应用就会显示为一个选项。您应该考虑使用主页按钮实现的目标。如果它不替换设备的默认主屏幕,我会担心重载HOME按钮,但它是可能的(根据上面的讨论中的讨论。)

答案 1 :(得分:21)

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

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

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

希望它有所帮助!

答案 2 :(得分:12)

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

以上唯一的例外是任何配置为家庭替代品的应用。这意味着它在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

答案 3 :(得分:7)

我发现当我按下HOME按钮时,会调用onStop()方法。您可以使用以下代码来监控它:

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

答案 4 :(得分:3)

使用BroadcastReceiver

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
                }
            }
        }
    }
}

答案 5 :(得分:2)

KeyEvent.KEYCODE_HOME不能被截获。

如果可能的话会很糟糕。

(编辑):我只看到Nicks的答案,这是完全完整的;)

答案 6 :(得分:2)

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

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 event),设置变量并在onpause事件中检查这个变量..

答案 7 :(得分:2)

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

答案 8 :(得分:1)

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

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

  

使用布尔值

保持应用程序在SharedPreferences上的状态

每项活动

  

onResume() - &gt; set appactive = true

     

onPause() - &gt; set appactive = false

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

  

如果appactive = false

它适用于我,至少不再耗尽电池, 希望这会有所帮助......

答案 9 :(得分:0)

像这样定义 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>