Detecting physical Menu key press in Android

2019-01-11 12:46发布

问题:

I am trying to detect when the physical Menu button on my Android phone has been pressed. I though the code below would work but it does not. Where am I going wrong please?

The error returned is 'Illegal modifier for parameter onKeyDown; only final is permitted'

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

回答1:

I'd look for an up key event, rather than a down event, with onKeyUp.

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

We return true because we're handling the event; return false if you want the system to handle the event too.

You can do all of this in your Activity instance too because Activity is a known indirect subclass of KeyEvent.



回答2:

Based on all of the above this appears to be the correct implementation that will consume menu key "up" events only and pass on other key events to the superclass.

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


回答3:

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


回答4:

Make sure you override the onKeyDown method in your Activity class. There is another onKeyDown method in the View class but it wont be called if the menu key is pressed.



回答5:

If you did handle the event just return true, if you didn't return false so the Android system can pass the event to the rest of the components to handle it.



回答6:

I have a very cool answer of this question I have tried it from the past 1 year and just found out the solution.

Please look at the answer below.

Create a class with the name of HomeWatcher. Exactly use the below code with the name of 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();

                        }*/

                    }
                }
            }
        }
    }
}

You need to declare the Homewatcher on your desired class where you wanted to detect the home button and Recent apps button.

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

    }

In the end of this you just need to add onPause and onResume Overide method like this.

@Override
    protected void onResume() {
        super.onResume();

        try {
            mHomeWatcher.startWatch();

        } catch (Exception e) {
        }
    }
    @Override
    protected void onPause() {
        super.onPause();

        try {
            mHomeWatcher.stopWatch();

        } catch (Exception e) {
        }
}

A very simple and beautiful answer. Waiting for the votes and accepted answer :p