Using onKeyDown with KEYCODE_MENU do nothing but it work with KEYCODE_SEARCH
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch(keyCode){
case KeyEvent.KEYCODE_MENU:
Toast.makeText(this, "Menu key pressed", Toast.LENGTH_SHORT).show();
return false;
case KeyEvent.KEYCODE_SEARCH:
Toast.makeText(this, "Search key pressed", Toast.LENGTH_SHORT).show();
return false;
}
return super.onKeyDown(keyCode, event);
}
I think there is something handling the menu key so it won't listen to my code
i have tried disbling onCreateOptionsMenu like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
But still won't work..
So, any ideas to make the menu button listen to onKeyDown??
This may be a bug in appcompat v22. See https://code.google.com/p/android/issues/detail?id=159795
The workaround as posted in that thread is to override dispatchKeyEvent :
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
int action = event.getAction();
boolean isDown = action == 0;
if (keyCode == KeyEvent.KEYCODE_MENU) {
return isDown ? this.onKeyDown(keyCode, event) : this.onKeyUp(keyCode, event);
}
return super.dispatchKeyEvent(event);
}
Edit: Please see Upgraded to AppCompat v22.1.0 and now onKeyDown and onKeyUp are not triggered when menu key is pressed
Even in use of Setup Box and Android TV
you can use dispatchKeyEvent in Activity and after that detect any key you want
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int code = event.getKeyCode();
int action = event.getAction();
boolean isDown = action == 0;
if (code == KeyEvent.KEYCODE_MENU) {
Toast.makeText(this, "Menu Is Selected", Toast.LENGTH_SHORT).show();
}
return super.dispatchKeyEvent(event);
}
What device and OS are you on ?
You may want to update your compat library to the latest ..
23.0.0
Related
I want to detect when the power button has been pressed (not long press) in my app.
I'm using the following code:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Log.d("mytag", "keycode_power");
return true;
}
return super.onKeyDown(keyCode, event);
}
However, nothing prints to log. I've also tried:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Log.d("mytag", "power off");
}
return super.dispatchKeyEvent(event);
}
but that doesn't work either.
Any suggestions?
I'm No Expert, But I Don't Think That The Power Button Counts As A Keypress
As I described in the Title, my problem is that there is a view that is not focusable. So now I've no idea how to get KeyEvents from the View...
Edit:
If possible, event can be listened from service
I have used this code in a fragment to close a full screen pager view and it works
View v = inflater.inflate(R.layout.fragment_addetails, container1,
false);
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& pager.getVisibility() == View.VISIBLE) {
pager.setVisibility(View.GONE);
return true;
}
return false;
}
});
or this
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
//do code
return true
}
return false;
}
maybe this will help
if not please describe the full scenario for what your are trying to achieve
Ok I found out, that I can use the MediaButton to get the KeyEvent I wanted. I just needed to declare a BroadcastReceiver and register it. Thats it!
I want to implement a KioskMode, I'm targeting only Android L, since this is a very specific App.
I already went through the process of setting my App as DeviceAdmin, and
DevicePolicyManager.isLockTaskPermitted(this.getPackageName()) already returns true.
I then start a LockTask via startLockTask().
Everything is fine, but when I hold down the backbutton, the app still exits the kiosk mode.
I have overridden onKeyPress to show a custom Dialog for unlocking the app, but this does not hinder android to automatically exit my lock task if the user holds down back.
I don't really know what to do at the moment and would be thankful for every input.
I now have overridden
#Override
public boolean onKeyDown(int KeyCode, KeyEvent event)
{
if(KeyCode == KeyEvent.KEYCODE_BACK)
{
BackDownButtonPressed = true;
if(VolDownPressed)
showTaskLockDialog();
return true;
}
else if(KeyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
VolDownPressed = true;
if(BackDownButtonPressed)
showTaskLockDialog();
return true;
}
return super.onKeyDown(KeyCode, event);
}
#Override
public boolean onKeyUp(int KeyCode, KeyEvent event) {
if(KeyCode == KeyEvent.KEYCODE_BACK)
{
BackDownButtonPressed = false;
return true;
}
else if(KeyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
VolDownPressed = false;
return true;
}
return super.onKeyUp(KeyCode, event);
}
#Override
public void onBackPressed()
{
return;
}
#Override
public boolean onNavigateUp() {
return true;
}
#Override
public boolean dispatchKeyEvent (KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return true;
}
return true;
}
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//do something or nothing in your case
return true;
}
return super.onKeyLongPress(keyCode, event);
}
For the record, I am using a Samsung SM-T700 Tablet with Cyanogenmod CM12.1
Just to close this topic..
I couldn't figure out a perfect solution to this day. My current workaround is receiving an event if the user leaves the kiosk mode and just entering the kiosk mode again.
Sadly this leaves the user with 2 toasts saying "screen unpinned" and "screen pinned", which is unfortunate. But this satisfies my current needs.
Perhaps you need to override onKeyLongPress
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//do something or nothing in your case
return true
}
return super.onKeyLongPress(keyCode, event);
}
Not sure if it's helpful at all, but I wrote a blog about setting Kiosk Mode here:
http://www.sureshjoshi.com/mobile/android-kiosk-mode-without-root/
And also wrote sample code for it here:
https://github.com/sureshjoshi/android-kiosk-example
Not sure if you see any major differences between your code and mine, but I just tried to do a long press on a Samsung Galaxy Tab 4 running Android 5.0, and it won't exit the app.
Could it be something with rooting with Cyanogen?
If you don't have this in your code, perhaps add it in and check out if you see any problems:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Remove title bar and notification bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ComponentName deviceAdmin = new ComponentName(this, AdminReceiver.class);
mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
if (!mDpm.isAdminActive(deviceAdmin)) {
Toast.makeText(this, getString(R.string.not_device_admin), Toast.LENGTH_SHORT).show();
}
if (mDpm.isDeviceOwnerApp(getPackageName())) {
mDpm.setLockTaskPackages(deviceAdmin, new String[]{getPackageName()});
} else {
Toast.makeText(this, getString(R.string.not_device_owner), Toast.LENGTH_SHORT).show();
}
mDecorView = getWindow().getDecorView();
}
and
protected void enableKioskMode(boolean enabled) {
try {
if (enabled) {
if (mDpm.isLockTaskPermitted(this.getPackageName())) {
startLockTask();
mIsKioskEnabled = true;
} else {
Toast.makeText(this, getString(R.string.kiosk_not_permitted), Toast.LENGTH_SHORT).show();
}
} else {
stopLockTask();
mIsKioskEnabled = false;
}
} catch (Exception e) {
// TODO: Log and handle appropriately
}
}
I have the same problem: How to stop "holding the back button" from escaping "Lock Task mode" on Android 6+
The issue only occurs on my Android 7 tablet.
Running the app on my Android 6 tablet fixed the problem.
Could you add some code to illustrate your current work-around?
I'm trying to detect when "Go" is pressed on the android Keyboard (the last key on the bottom right).
My code works in the emulator and on my Nexus 5, but doesn't on some other Android devices.
What am I doing wrong?
editTextMain.setImeActionLabel("Go", KeyEvent.KEYCODE_ENTER);
editTextMain.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if(i==KeyEvent.KEYCODE_ENTER)
{
Intent intent = new Intent(thisActivity, ActivityRisultati.class);
startActivity(intent);
return true;
}
}
}
Try this
editText = (EditText) findViewById(R.id.edit_text);
editText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// do your stuff here
}
return false;
}
});
I have some code in my app which detects when any key which sends the KEYCODE_ENTER value is pressed. It detects both the Enter and Done keys on a Motorola Droid 3 slide-out keyboard. Here's my code:
private OnKeyListener enterKeyListener = new OnKeyListener()
{
public boolean onKey(View v, int k, KeyEvent e)
{
/*
* "Enter" or "Done" key was pressed
*/
if( (e.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (e.getAction() == KeyEvent.ACTION_UP) )
{
//
// Do some stuff ...
//
return true;
}
return false;
}
};
Note the additional check for KeyEvent.ACTION_UP. You might need that on some devices in order to prevent the listener from firing as soon as the button is pressed, and repeatedly if the button is held down. In my case, I only wanted it to take an action if the key had been pressed and then released.
Hope this helps.
I want to do a custom action when pressing on the Menu button on the phone.
Is it possible to set an onClickListener (or similar) on the button and if so, how?
onCreateOptionsMenu is only called the first time the button is pressed - I've already tried this.
Usually you shouldn't override MENU behavior as users expect menu to appear, however you can use something along these lines:
/* (non-Javadoc)
* #see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ( keyCode == KeyEvent.KEYCODE_MENU ) {
Log.d(TAG, "MENU pressed");
return true;
}
return super.onKeyDown(keyCode, event);
}
But onPrepareOptionsMenu(..) is called each time. :)
Updated for AppCompat v.22.+
As mentioned in this forum, KeyDown is not called for KEYCODE_MENU button pressed.
The solution is to override dispatchKeyEvent to this way:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
int action = event.getAction();
boolean isDown = action == KeyEvent.ACTION_DOWN;
if (keyCode == KeyEvent.KEYCODE_MENU) {
return isDown ? this.onKeyDown(keyCode, event) : this.onKeyUp(keyCode, event);
}
return super.dispatchKeyEvent(event);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ( keyCode == KeyEvent.KEYCODE_MENU ) {
// do what you want to do here
return true;
}
return super.onKeyDown(keyCode, event);
}
It works until Google developers release a fix for this (or maybe it is not a bug and it works this way from now on).
You could probably hack something in using "OnMenuOpened" or some such, but I really wouldn't recommend it. The menu button is only supposed to be used to show menus, so there is consistency between applications.