13

I would like to create a photo/video capture application.

I have created a CaptureView class which extends SurfaceView and placed it in the main form.

The main form's activity has onCreateOptionsMenu() method which creates a menu. The menu worked fine but then I tried to implement a method onKeyDown:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    if(event.getAction() == KeyEvent.ACTION_DOWN) {
        switch(keyCode) {
        case KeyEvent.KEYCODE_CAMERA:
            videoPreview.TakePicture();
            return true;
        }
    }

    return super.onKeyDown(keyCode, event);
}

The menu doesn't appear anymore and the method doesn't catch onKeyDown event.

Does anyone know what could be the reason for this issue?

mmBs
  • 8,421
  • 6
  • 38
  • 46
Niko Gamulin
  • 66,025
  • 95
  • 221
  • 286

8 Answers8

14

I had a similar problem and solved it by adding

this.requestFocus();
this.setFocusableInTouchMode(true);

in the constructor of my SurfaceView subclass.

Ciryon
  • 2,637
  • 3
  • 31
  • 33
  • thanks, that worked for me. I was using a viewflipper to move between views, and wanted to override the back button to set a view as current view. Adding a webview to the VF stopped firing onKeyDown. Setting requestFocus and setFocusableInTouchMode on the VF sorted it out. Thanks again – Veeru Jul 05 '11 at 05:42
12

I found that I was returning true for all events, where I should only have been returning it for the code that I was using. I moved the return true inside the scope of the if statement and returned false otherwise That brought my menu back!

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    super.onKeyDown(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        dba.close();
        Intent result = new Intent("Complete");
        setResult(Activity.RESULT_OK, result);
        finish();
        return true;
    }
    return false;
}
Rahul Sharma
  • 2,867
  • 2
  • 27
  • 40
  • 1
    Sorry always returning false used to work in older SDK but will lead to trouble: when compiling with ICS, this approach will disable the back key. of course in your specific case it is working as you are precisely consumming back key event, but in generally it will not work as expected. – Thierry Nov 12 '11 at 15:42
  • 7
    -1. The best answer involves 'return super.onKeyDown(keyCode, event);', instead of always returning false when you don't handle the key down, as posted by rrabio. – leetNightshade Jan 09 '13 at 00:04
  • The onKeyDown() method is not at all called while pressing the hardware search button, instead search default behaviour is triggered. But pressing back or menu button trigger this method. How can I listen the android hardware search button click.? – Karthick Jun 07 '13 at 09:44
6

i solved removing the if statement, like this:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch(keyCode)
    {
        case KeyEvent.KEYCODE_CAMERA:
            videoPreview.TakePicture();
            return true;
    }
    return super.onKeyDown(keyCode, event);
}
Emond
  • 50,210
  • 11
  • 84
  • 115
rrabio
  • 143
  • 2
  • 6
  • yes good point. always returning false at the end used to work for me, but when compiling with new ICS SDK, the back key does not work any more as the event seems to be consumed now in super.onKeyDown – Thierry Nov 12 '11 at 15:39
4

I don't know why sometimes it does not work, though for one of my apps this keyDown() is working fine and again when I use it for a new app then it does not work.

But I have a solution which always works:

@Override
public boolean dispatchKeyEvent (KeyEvent event) {
    if (event.getAction()==KeyEvent.ACTION_DOWN && event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
        Toast.makeText(this, "Back button pressed", Toast.LENGTH_LONG).show();
        return true;
    }
    return false;
}
Tim M.
  • 53,671
  • 14
  • 120
  • 163
enam
  • 952
  • 11
  • 11
2

I solved this by adding into constructor this code:

setFocusable(true);
requestFocus();

thanks, Ciryon

Also every time I use setContentView(myView); I must call myView.requestFocus();. If there is a better solution please tell me.

Community
  • 1
  • 1
alaster
  • 3,821
  • 3
  • 24
  • 32
1

you can try this

this.setFocusable(true);
Lucifer
  • 29,392
  • 25
  • 90
  • 143
zhujian
  • 11
  • 1
1

Well, in looking at the API documentation the only thing that stands out is that the android:clickable attribute must be set as well as the view being enabled for the onKeyDown(...) method to work.

Dean
  • 939
  • 10
  • 30
0

Your Activity could be eating the key event. Override onKeyDown in the activity and throw a breakpoint in there.

Also: when you say you've "placed it in the main form" are you using the XML layout or doing in your code?

haseman
  • 11,213
  • 8
  • 41
  • 38