3

I need to read a barcode for an application. I am using trigger barcode scanner for this. Communication is via USB.

As you know, barcode scanners work like keyboards. When the device reads the barcode, it tries to write the value to the input that has focus. And the user presses the trigger, the barcode scanner works until the barcode is read successfully. Then it takes itself in standby mode. Ideal way to read a lot of barcodes.

The problem is that after the user presses the trigger and reads the barcode, the focus of the EditText disappears. Focus is going to another view in the same layout randomly. When the user tries to read one more barcode, the operation fails because there is no focus on related EditText.

What did I try?

android:windowSoftInputMode="stateAlwaysVisible"

Added above line to the manifest file

android:focusable="true"
android:focusableInTouchMode="true"

Added above lines on the xml side.

 edtBarcode.setOnFocusChangeListener(new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
            if (!hasFocus)
            {
                //find the view that has focus and clear it.
                View current = getCurrentFocus();
                if (current != null)
                {
                   current.clearFocus();
                } 

                edtBarcode.requestFocus();
            }
        }
    });

It detects when EditText loses its focus. But i can't assign it back. I ensure that the EditText is focusable in touch mode.

How did i solve it?

    handlerFocus = new Handler();
    final int delay = 1000; //milliseconds

    handlerFocus.postDelayed(new Runnable()
    {
        public void run()
        {
            edtBarcode.requestFocus();
            handlerFocus.postDelayed(this, delay);
        }
    }, delay);

I know this solution is not good. So how do I make the focus always stay in the same EditText without opening the keyboard?

CRITICAL EDIT

After 4 years, I realized that the approach above was completely wrong. The better approach here and I do not remove the old one because it can work for someone else.

You should override dispatchKeyEvent to intercept all key events before they are dispatched to the window. Be sure to call this implementation for key events that should be handled normally.

    String barcode = "";

    @Override
    public boolean dispatchKeyEvent(KeyEvent e)
    {
        if (e.getAction() == KeyEvent.ACTION_DOWN)
        {
            char pressedKey = (char) e.getUnicodeChar();
            barcode += pressedKey;
        }
        if (e.getAction() == KeyEvent.ACTION_UP && e.getKeyCode() == KeyEvent.KEYCODE_ENTER)
        {
            handleInput(barcode);
            barcode = "";
        }

        return false;
    }
Burak Cakir
  • 893
  • 12
  • 19

4 Answers4

7

Basically when user presses the trigger, it triggers the KeyEvent on your EditText. Which can be KEYCODE_TAB or KEYCODE_ENTER, based on the scanner's configuration.

So what I did is to listen to the OnKeyEvent rather than the OnFocusChange.

Try this:

edtBarcode.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if ((event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER)
                    || keyCode == KeyEvent.KEYCODE_TAB) {
                // handleInputScan();
                new Handler().postDelayed(new Runnable() {
                      @Override
                      public void run() {
                          if (edtBarcode != null) {
                               edtBarcode.requestFocus();
                          }
                      }
                }, 10); // Remove this Delay Handler IF requestFocus(); works just fine without delay
                return true;
            }
            return false;
        }
    });

Hope this helps~

Jiyeh
  • 4,837
  • 1
  • 26
  • 29
0

Could you try:edtBarcode.setSelectAllOnFocus(true);

and to hide the keyboard you can try this one: Close/hide the Android Soft Keyboard

I hope I've helped.

Community
  • 1
  • 1
0

try this: in your manifest :

<activity android:name=".Activity.TransferBtwCenterAndStoresActivity"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateHidden"/>

and in your activity class :

edtBarcode.setFocusableInTouchMode(true);
edtBarcode.requestFocus();
cartoonworld
  • 107
  • 1
  • 6
0

Set the below mentioned listener in editText:

edtxt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int keyCode, KeyEvent event) {
            if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) {
                return false;
            }
            if (keyCode == EditorInfo.IME_ACTION_DONE) {
                //this is for DONE button in soft keyboard is pressed
                //your logic
                return true;
            }
            if (keyCode != EditorInfo.IME_ACTION_NEXT && keyCode != EditorInfo.IME_NULL) {
                return false;
            }
            //your logic
            // this will be called when hardware enter button is pressed eg. barcode enter enter code here
            return true;
        }
    };)