代码之家  ›  专栏  ›  技术社区  ›  n179911

如何检测用户在我的活动中按Home键?[复制品]

  •  12
  • n179911  · 技术社区  · 15 年前

    这个问题已经有了答案:

    你能告诉我我的活动是如何检测用户按下的吗 钥匙?

    谢谢您。

    11 回复  |  直到 9 年前
        1
  •  42
  •   Community CDub    8 年前

    更新 【2015年8月】:根据 JM Lord ,此答案可能不适用于棒棒糖及以上设备。见 Alternative to getRunningTasks in Android L


    虽然,这是一个老问题,但大多数答案在api级别17及以上的版本中对我都不起作用。我在回答最后对我有用的事情。我试过很多方法,但没有一个像今天这样有效。我试着回答

    Call method when home button pressed on android ,

    Detect home button press in android

    Overriding the Home button - how do I get rid of the choice? . 关键是家就像一个紧急逃生按钮。所以你不能覆盖它,但可以在某些方面检测到它。

    一些我试过的(包括上面的答案)和 没有工作 是:

    1. 使用 keyCode==KeyEvent.KEYCODE_HOME 在很多方面 如上所述。现在,如果你读了 KeyEvent.KEYCODE_HOME ,上面说 This key is handled by the framework and is never delivered to applications . 所以已经没有了 现在有效。

    2. 我试着用 onUserLeaveHint() . 文件上说:

      当一个活动 作为用户选择的结果进入后台。例如, 当用户按下Home键时,onuserleavehint()将 已呼叫,但当传入的电话导致拨入活动时 自动带到前台。

      问题是,当您启动 Activity 在你打电话的活动中 onUserleaveLint() , 就像我的情况一样。见 Android onBackPressed/onUserLeaveHint 更多的问题。所以不确定 只有按Home键才能通话。

    3. 打电话 onStop() . 当一个活动位于现有活动之上并完全覆盖它时,也可以调用它。所以这也行不通。

    最后 后续工作 为了我:

    看到 How to check current running applications in Android? 你可以说,如果你的任务是最近长时间按home按钮显示的,那么它被发送到后台。

    所以,在你的 onPause() 在尝试检测按下的“主页”按钮的活动中,可以检查应用程序是否已发送到后台。

    @Override
    public void onPause() {
        if (isApplicationSentToBackground(this)){
            // Do what you want to do on detecting Home Key being Pressed 
        }
        super.onPause();
    }
    

    功能检查您的应用程序是否是最近发送到后台的应用程序:

    public boolean isApplicationSentToBackground(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                return true;
            }
        }
        return false;
    }
    

    感谢@idish指出不要忘记在您的清单中包含以下权限:

    <uses-permission android:name="android.permission.GET_TASKS" />
    

    我不确定这是否有什么坏处,但这对我很有效。希望有一天它能帮助别人。

    P.S:如果您在使用 FLAG_ACTIVITY_NO_HISTORY 标记,则这将不起作用,因为它会检查最近的历史记录以确定 Home 已单击按钮。

        2
  •  12
  •   Springfeed    14 年前

    您可以通过activity.onUserLeaveHint()检测到主按钮按下。此方法在两种情况下调用:用户按Home键和启动新活动时。一定要把两者区别开来。

        3
  •  9
  •   Graeme    13 年前

    没有正式的方式可以得到“home”按键的通知。但是有一个非常简单的方法可以让你的应用程序区分“主页”按键和任何其他会导致活动停止的操作。

    对于需要对“主页”按键执行某些操作的每个类,请将它们从包含以下内容的活动扩展:

    /**************************************** On Home **********************************/
    private boolean leaveCalled = false;
    
    @Override
    public void startActivity(Intent intent) {  
        leaveCalled= true;
        super.startActivity(intent);
    }
    
    @Override
    public void onBackPressed() {
        leaveCalled = true;
        super.onBackPressed();
    }
    
    @Override
    protected void onStop() {   
        super.onStop();
        // Home button pressed
        if(!leaveCalled) {
            // Do whatever you like.
        }
    
        leaveCalled = false;
    }
    

    编辑

    您还需要从包含此内容的父类扩展片段。这是因为片段将提供一个额外的路径,在应用程序中以预期的而非“主”方式切换活动。

    @Override
    public void startActivity(Intent intent) {  
        getActivity().startActivity(intent);
    }
    

    编辑2

    我几乎认为这不是解决这个问题的最简单的方法…您还需要将onconfigurationchange=“orientation”添加到使用此方法的所有活动中。然后您可以添加:

    @Override
    public void onConfigurationChanged(Configuration newConfig) {   
        super.onConfigurationChanged(newConfig);
        leaveCalled = true;                     
        finish();
        startActivity(getIntent()); 
    }
    

    编辑3

    乌尔赫

    @Override
    public void finish() {
        leaveCalled = true;
        super.finish();
    }
    
        4
  •  8
  •   Mark B    15 年前

    你不能以任何方式捕获主事件并截获它。当用户按Home键时,将始终带到其设备的主屏幕。

    如果您需要知道何时将活动发送到后台,比如从用户按Home键或Back键,我将实现onstop()方法。

        5
  •  7
  •   Sujewan    10 年前

    在活动中使用onuserleavehint()方法

    @Override
    protected void onUserLeaveHint()
    {
       super.onUserLeaveHint();
    }
    

    http://developer.android.com/reference/android/app/Activity.html#onUserLeaveHint()

        6
  •  4
  •   Vikas Singh    13 年前

    它可以完成(至少正常运行2.3)。在Android版本2.3.5上测试,非根HTC Wildfire-S。捕获/禁用所有控制键的代码片段:

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();        
        this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
    
    
    }
    
    public boolean onKeyDown(int keyCode, KeyEvent event) {     
    
        if(keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH  )
        {
    
           Toast.makeText(getApplicationContext(),"You pressed a control button with keyCode : " + keyCode, Toast.LENGTH_SHORT).show();
           return false;
    
        }
        else
        {
            Toast.makeText(getApplicationContext(),"You pressed" + keyCode, Toast.LENGTH_SHORT).show();
        }
    
        return true;
    }
    
    public boolean onKeyUp(int keyCode, KeyEvent event) {     
    
        if(keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH  )
        {
    
           return false;
    
        }
        else
        {
            // Do nothing
        }
    
        return true;
    }
    
        7
  •  3
  •   Leo user370469    13 年前

    您可以编写广播侦听器并将筛选器设置为

    <category android:name="android.intent.category.HOME" />
    

    从广播接收器启动UR活动/通知活动。

        8
  •  2
  •   JM Lord    9 年前

    我根据@springfeed的建议找到了这个解决方案。这个问题非常普遍,请注意这个特殊的解决方案将:

    • 在棒棒糖和更低版本的android上工作(我以前基于activitymanager的代码在棒棒糖上失败了)
    • 捕获“主页”和“历史记录”按钮
    • 如果活动本身定义为home-always,则不会捕获home
    • 如果活动是许多家庭选项中的一个,或者根本不在家,则将捕获家庭。

    这个密码在我的基地里 Activity 类(所有活动都继承该类)

        public boolean startingActivity = false;
    
        @Override
        protected void onUserLeaveHint()
        {
            if(startingActivity)
            {
                // Reset boolean for next time
                startingActivity = false;
            }
            else
            {
                // User is exiting to another application, do what you want here
                Log.i(TAG, "Exiting");
                ...
            }
        }
    
        @Override
        public void startActivity(Intent intent)
        {
            startingActivity = true;
            super.startActivity(intent);
        }
    
        @Override
        public void startActivityForResult(Intent intent, int requestCode)
        {
            startingActivity = true;
            super.startActivityForResult(intent, requestCode);
        }
    

    由于某些方法也可能使用应用程序上下文来启动意图,因此我定义了一个由应用程序类持有的ContextWrapper来切换布尔值(请注意,我可以通过该基类静态访问自己应用程序的最顶层活动)。

    public class MyContext extends ContextWrapper
    {
    
        public MyContext(Context base)
        {
            super(base);
        }
    
        @Override
        public void startActivity(Intent intent)
        {
            BaseActivity activity = BaseActivity.getActivity();
            if(activity != null)
            {
                activity.startingActivity = true;
            }
    
            super.startActivity(intent);
        }
    
    }
    

    如果有必要的话,人们可能还想覆盖startactivities(…)。

    希望这有帮助:)

        9
  •  -1
  •   Anthony    15 年前
    android.text.method.KeyListener.onKeyDown([view],[text],KEYCODE_HOME,[event])
    

    我不知道其他参数是如何适应的,甚至不知道如何实现上面的功能,但是这些信息都在keylistner中。 documentation .

    但他们也提到 another page 家里的钥匙总是放在家里,你不能改变。所以,如果你计划进行某种“你确定你想退出”的对话,那就行不通了。

        10
  •  -1
  •   AJ0    9 年前
    public boolean isApplicationSentToBackground(final Context context) {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
            if (!tasks.isEmpty()) {
                ComponentName topActivity = tasks.get(0).topActivity;
                if (!topActivity.getPackageName().equals(context.getPackageName())) {
                    return true;
                }
            }
            return false;
        }
    
    
    
     public void onPause() {
        super.onPause();
        if(isApplicationSentToBackground(this))
        {
            Log.i("Home", "Home Pressed..!");
        }
     }
    
        11
  •  -8
  •   hharry    12 年前
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {     
    
        if(keyCode == KeyEvent.KEYCODE_HOME)
        {
    
           //The Code Want to Perform. 
    
        }
    });