This question already has answers here:
Detect two hardware button press simultaneously
(2 answers)
Closed 6 years ago.
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode==KeyEvent.KEYCODE_VOLUME_DOWN && keyCode==KeyEvent.KEYCODE_VOLUME_UP )
textView.setText("both buttons are pressed");
return true;
}
The problem is, when I use single comparison in if () then it works correctly. but when I use 2 comparison in single if() using && then it doesn't work. actually I want to perform action when volume up and volume down buttons are pressed at a same time.
onKeyDown() is fired twice when each key is pressed down. what you need is to use two individual if()s which increment an int onKeyDown that is initialised to zero and decrement it onKeyUp then also each check if the int is equal to 2 in onKeyUp, if true carry out an action u require which will be in a method you call
Sudo code:
int i = 0;
public void onKeyDown(int keyCode, KeyEvent event){
if(keyCode==KeyEvent.KEYCODE_VOLUME_DOWN){
i++;
}
if(keyCode==KeyEvent.KEYCODE_VOLUME_UP ){
i++;
}
if(i == 2 ){
action();
}
}
public void onKeyUp(int keyCode, KeyEvent event){
if(keyCode==KeyEvent.KEYCODE_VOLUME_DOWN){
i--;
}
if(keyCode==KeyEvent.KEYCODE_VOLUME_UP ){
i--;
}
}
private void action(){
// AND ACTION!!!
}
Related
How can I set a listener for long-click performed on hardware Menu button? What is the way of programmatic access to the Menu button?
Moreover how can I distinguish long-click from single-click? (As far as I know when long-click is performed the single-click event is propagated as well - I do not want this to happen because I need 2 different actions for these 2 situations. Long-click and single-click separate listeners for the device Menu button)
Thank you!
This shoule be fairly straight forward. Check out the KeyEvent.Callback on the Android developer's website.
There you will find onKeyLongPress() as well as onKeyDown() and onKeyUp(). This should get you on the right track. Comment or post you code if you need any further help.
Edit: I just re-read the question. If you are having trouble distinguishing single click from long click, you will need to use onKeyDown and onKeyUp and check the duration of the click. Esentially you will start a timer in the onKeyDown and check the time in the onKeyUp. You will have to watch for FLAG_CANCELED.
Further Edit: I found the time to do a couple of tests. This code should do what you want (onKeyUp() gets only short press events and onLongPress() gets only long press events).
The key thing here is in the call to event.startTracking() in the onKeyDown() handler.
Place in Activity (this should also work in a custom view as well but untested):
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
// Handle Long Press here
Log.i("KeyCheck", "LongPress");
return true;
}
return super.onKeyLongPress(keyCode, event);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i("KeyCheck", "KeyDown" + keyCode);
if (keyCode == KeyEvent.KEYCODE_MENU) {
event.startTracking(); //call startTracking() to get LongPress event
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.isTracking()
&& !event.isCanceled()) {
// handle regular key press here
Log.i("KeyCheck", "KeyUp");
return true;
}
return super.onKeyUp(keyCode, event);
}
i am using AutoCompleteTextView in my Activity and i need it's DropDownList to be shown all the time (it's the only View in Window), even after Back key press. I need to dismiss soft keyboard instead.
I tried to override Activity's onBackPressed method, but it's not used at all, so BackPressed event is being handled somewhere "higher". So i tried to find out where, but AutoCompleteTextView has no onBackPressed method defined.
Any advices?
You can create your custom AutoCompleteTextView and Override the method onKeyPreIme(int keyCode, KeyEvent event)
I also realized that this method is called 2 times, I'm running my code only in the second time. Here is the example:
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == 1) {
//add your code here
return true;
}
return super.onKeyPreIme(keyCode, event);
}
You may try this
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//Your back key press logic
}
return true;
}
Remember to return true to prevent this event from being propagated further, or false to indicate that you have not handled this event and it should continue to be propagated.
I am developing an app in which i am using custom list tab,By using this custom list tab i am rendering some child activities, and some of the child activities are having some soft key pad functionality now the problem is when i click on the back hard key(when the soft key pad is on) it is simply killing the activity with out firing OnkeyDown() and onBackpress() events and it is firing onDestroy() event method and this issue is specially occurring in HTC Devices. And the other devices(samsung) are working as exppect i.e. hiding the soft key pas on pressing hard back key. how to this issue?
Thanks,
Ram.
You can try overriding onKeyDown and onKeyUp like this:
#Override
public boolean onKeyDown( int keyCode, KeyEvent event )
{
if ( keyCode == KeyEvent.KEYCODE_BACK )
{
return true;
}
return super.onKeyDown( keyCode, event );
}
#Override
public boolean onKeyUp( int keyCode, KeyEvent event )
{
if ( keyCode == KeyEvent.KEYCODE_BACK )
{
onBackPressed();
return true;
}
return super.onKeyUp( keyCode, event );
}
I remember reading this to be a problem in Android versions earlier than 2.1
I have an onKeyDown Event which is supposed to display an image once triggered, but I have noticed that despite pressing the corresponding key several times, the image does not appear until I click anywhere on the canvas with my mouse. Any suggestions on the actual problem and how to proceed? Pretty new to the concept so not quite sure what may be missing.
*Edited and pasted class in its entirety.
Thanks
public class BuccaneerView extends TileView {
public static final int PLAYER = 1;
public static final int GREEN_STAR = 2;
Coordinate P_Location;
public BuccaneerView(Context context, AttributeSet attrs) {
super(context, attrs);
initBucc();
}
private void initBucc() {
this.setFocusable(true);
Resources r = this.getContext().getResources();
resetTiles(4);
loadTile(PLAYER, r.getDrawable(R.drawable.aerialplayer));
loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar));
/**/
P_Location = new Coordinate(5,5);
setTile(PLAYER, P_Location.x, P_Location.y);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
if (keyCode == KeyEvent.KEYCODE_SPACE)
{
setTile(GREEN_STAR, 1, 0);
}
return super.onKeyDown(keyCode, msg);
}
public void update()
{
}
}
You seem to be treating onKeyDown as one of your on methods.
return super.onKeyDown(keyCode, msg);
Is a bad thing to do, its as if you have called this function and want to return what key has been pressed. Change it to simply be return false which will mean you are handling what they keyboard is doing.
EDIT
Is there any reason you use onKeyDown and not onKey? Here is some extra code which I use, it uses an array of booleans (pressedKeys, which is 128 in length) and you can later use it to check the array to see if a key is pressed
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == android.view.KeyEvent.ACTION_DOWN)
{
if(keyCode > 0 && keyCode < 127)
pressedKeys[keyCode] = true;
}
if (event.getAction() == android.view.KeyEvent.ACTION_UP)
{
if(keyCode > 0 && keyCode < 127)
pressedKeys[keyCode] = false;
}
keyEventsBuffer.add(keyEvent);
}
return false;
}
So with this you can then say
If(pressedKeys[KeyYouWantToCheck])
{
//Do some stuff if that key is down
}
At a guess, the key event is not being delivered to whatever you have set the key listener on. This can happen if there is another view in between which is a listener and which stops the propagation of the key event (i.e. returning true from this method). There are some views which do this by default (e.g. EditText for most keys). It would be helpful if you could edit your question and include more code, or describe how your activity is setup.
By 'clicking on the canvas' you are probably changing the focus and making the key event being delivered to a different view. This could explain why you suddenly see the key listener working after clicking.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
public boolean onKey() called twice?
Display.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
solveExpression();
return true;
}
return false;
}
});
I'm trying to solve the expression contained within the Display(EditText), by pressing the enter button on the keyboard, yet it always interprets it as though I pressed the button twice. Does anyone know why this happens?
Try...
Display.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
// Check for ACTION_DOWN only...
if (KeyEvent.ACTION_DOWN == event.getAction()) {
solveExpression();
return true;
}
}
}
});
The 'action' can be ACTION_DOWN, ACTION_UP or ACTION_MULTIPLE (the last being for when a key is pressed and held). onKey() will be called for any/all of those actions.
As the other answer mentions, it's triggering twice because it's once for down and once for up.
if (event.getAction()!=KeyEvent.ACTION_DOWN) // we catch only key down events
return true;
Thus you stop listening other keyevents as onClick.
If you want nobody else further in chain to get the event for another piece of work, you should set
return false;
not an android guy either but the fact that it registers twice makes me think that OnKey encompasses a onKeyDown and onKeyUp. Would listening to onKeyUp work for you as well?