【问题标题】:Detecting physical Menu key press in Android在Android中检测物理菜单按键
【发布时间】:2011-05-13 11:56:36
【问题描述】:

我正在尝试检测我的 Android 手机上的物理菜单按钮何时被按下。我虽然下面的代码可以工作,但它没有。请问我哪里出错了?

返回的错误是'Illegal modifier for parameter onKeyDown;只允许final'

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_MENU) {
        // Do Stuff
    } else {
        return super.onKeyDown(keyCode, event);
    }
}

【问题讨论】:

  • 如果你能接受一个答案那就太好了,因为这个问题现在已经得到了彻底的回答。

标签: android button


【解决方案1】:

如果你确实处理了事件就返回true,如果你没有返回false,那么Android系统可以将事件传递给其余的组件来处理它。

【讨论】:

    【解决方案2】:

    我会寻找 up 键事件,而不是 down 事件,onKeyUp

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU) {
            // ........
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }
    

    我们返回true 因为我们正在处理事件;如果您希望系统也处理该事件,请返回 false

    您也可以在 Activity 实例中执行所有这些操作,因为 ActivityKeyEvent 的已知间接子类。

    【讨论】:

    • 还可以查看文档KeyEvent.Callback,这里是example
    • 这是一个错误的答案,它永远不会起作用。请看下面的答案。
    • 像魅力一样为我工作。我对此持怀疑态度,因为我一开始尝试了 onKeyDown(),但菜单按钮的事件从未渗透到我的活动中,而是在“操作”工具栏中的某处被消耗。
    • 至少不适用于搭载 Android 10 的三星 S10+。
    【解决方案3】:

    基于以上所有内容,这似乎是正确的实现,它将仅使用菜单键“向上”事件并将其他键事件传递给超类。

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU) {
            // ...
            return true;
        } else {
            return super.onKeyUp(keyCode, event);
        }
    }
    

    【讨论】:

    • 这应该总结一下,返回 true 否则调用超类。
    • 最佳答案不正确吗?似乎是一样的。对 else 块中的 return 有影响吗?
    • @TamásBolvári 最佳答案也很好。不需要 else 块。
    • 至少不适用于搭载 Android 10 的三星 S10+。
    【解决方案4】:
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
        //Checking for the "menu" key
        if (keyCode == KeyEvent.KEYCODE_MENU) { 
            if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
                mDrawerLayout.closeDrawers();
            } else {
                mDrawerLayout.openDrawer(Gravity.RIGHT);
            }
            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }
    

    【讨论】:

    • 我正在寻找这个确切的代码 :) 隐藏和显示左侧导航抽屉。谢谢。
    • 这似乎和问题中的检测方法相同。唯一的区别是returning trueif 块中。如果这是解决问题所需的唯一事情,则应明确说明,并删除不相关的部分(mDrawerLayout 内容)。那么这可能比当前的顶级解决方案更好,因为这个答案不需要将onKeyDown 更改为onKeyUp,只需在if 块中添加return true;。当然,只有当它有效时......
    【解决方案5】:

    确保覆盖 Activity 类中的 onKeyDown 方法。 View 类中还有一个 onKeyDown 方法,但是如果按下菜单键则不会调用它。

    【讨论】:

      【解决方案6】:

      我对这个问题有一个非常酷的答案 我从过去 1 年开始尝试过,刚刚找到了解决方案。

      请看下面的答案。

      创建一个名为 HomeWatcher 的类。 正确使用下面的代码,名称为 HomeWatcher。

      public class HomeWatcher {
          static final String TAG = "HomeWatcher";
          private Context mContext;
          private IntentFilter mFilter;
          private OnHomePressedListener mListener;
          private InnerRecevier mRecevier;
      
          public interface OnHomePressedListener {
              public void onHomePressed();
      
              public void onHomeLongPressed();
      
              //public void onLockLongPressed();
          }
      
          public HomeWatcher(Context context) {
              mContext = context;
              mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
          }
      
      
          public void setOnHomePressedListener(OnHomePressedListener listener) {
              mListener = listener;
              mRecevier = new InnerRecevier();
          }
      
          public void startWatch() {
              try{
              if (mRecevier != null) {
                  mContext.registerReceiver(mRecevier, mFilter);
              }
              }catch(Exception e){}
          }
      
      
          public void stopWatch() {
              try{
              if (mRecevier != null) {
                  mContext.unregisterReceiver(mRecevier);
              }
              }catch(Exception e){}
          }
      
      
          class InnerRecevier extends BroadcastReceiver {
              final String SYSTEM_DIALOG_REASON_KEY = "reason";
              final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
              final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
              final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
              //final String SYSTEM_DIALOG_REASON_Lock = "lock";
      
              @Override
              public void onReceive(Context context, Intent intent) {
                  String action = intent.getAction();
                  if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                      String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
      
                      if (reason != null) {
                          Log.e(TAG, "action:" + action + ",reason:" + reason);
                          if (mListener != null) {
                              if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                                  mListener.onHomePressed();
                              } else if (reason
                                      .equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                                  mListener.onHomeLongPressed();
      
                              }
                          /*  else if (reason
                                      .equals(SYSTEM_DIALOG_REASON_Lock)) {
                                  mListener.onLockLongPressed();
      
                              }*/
      
                          }
                      }
                  }
              }
          }
      }
      

      您需要在想要检测主页按钮和最近应用程序按钮的所需类上声明 Homewatcher。

      public class MainActivity extends  Activity {
      
          private HomeWatcher mHomeWatcher;
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
               setContentView(R.layout.activity_main);
          try {
      
                  mHomeWatcher = new HomeWatcher(this);
                  mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
                      @Override
                      public void onHomePressed() {
                          Log.e(TAG, "onHomePressed");
      
      
                      }
                     @Override
                      public void onHomeLongPressed() {
                          Log.e(TAG, "recent apps");
      
                      }
      
      
                  });
                  mHomeWatcher.startWatch();
              } catch (Exception e) {
              }
      
          }
      

      最后你只需要像这样添加 onPause 和 onResume Overide 方法。

      @Override
          protected void onResume() {
              super.onResume();
      
              try {
                  mHomeWatcher.startWatch();
      
              } catch (Exception e) {
              }
          }
          @Override
          protected void onPause() {
              super.onPause();
      
              try {
                  mHomeWatcher.stopWatch();
      
              } catch (Exception e) {
              }
      }
      

      一个非常简单而美丽的答案。等待投票和接受的答案:p

      【讨论】:

        猜你喜欢
        • 2022-01-03
        • 1970-01-01
        • 2017-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-18
        • 2011-10-14
        相关资源
        最近更新 更多