Android device Bluetooth connection scanning gun obtains scanning content

  • 2021-12-21 05:01:04
  • OfStack

The bar scanning gun can mainly scan bar codes and 2D codes, and the scanning speed is much faster than that of mobile phone scanning equipment. This paper briefly introduces that android monitors Bluetooth connection through Bluetooth. When the connection of scanning equipment is completed, the scanning equipment is equivalent to an external keyboard, and the scanned content can be obtained by monitoring the input events of the external keyboard.
Other reference documents: Android device obtains scanning content of code scanning gun

1. Bluetooth pairing

Open the system settings, Bluetooth matching scanning gun, 1 scanning gun instructions are written, after the pairing is completed, it shows that it has been connected

2. Configure permissions in AndroidManifest

Configure the permissions required for Bluetooth connection in


<!--  Bluetooth  -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

3. Obtain equipment information and judge whether to connect or not

The device type returned by the Bluetooth device is BluetoothClass. Device. Major. PERIPHERAL


/**
     *  Is the scanning gun connected 
     * @return
     */
    public boolean hasScanGun() {
        if (mBluetoothAdapter == null) {
            return false;
        }
        Set<BluetoothDevice> blueDevices = mBluetoothAdapter.getBondedDevices();
        if (blueDevices == null || blueDevices.size() <= 0) {
            return false;
        }
        for (Iterator<BluetoothDevice> iterator = blueDevices.iterator(); iterator.hasNext(); ) {
            BluetoothDevice bluetoothDevice = iterator.next();

            if (bluetoothDevice.getBluetoothClass().getMajorDeviceClass() == BluetoothClass.Device.Major.PERIPHERAL) {

                mDeviceName = bluetoothDevice.getName();
                return isInputDeviceExist(mDeviceName);
            }
        }
        return false;
    }
    /**
     *  Does the input device exist 
     * @param deviceName
     * @return
     */
    private boolean isInputDeviceExist(String deviceName) {
        int[] deviceIds = InputDevice.getDeviceIds();

        for (int id : deviceIds) {
            if (InputDevice.getDevice(id).getName().equals(deviceName)) {
                return true;
            }
        }
        return false;
}

4. Build the scanning gun parsing class ScanGunKeyEventHelper

Using the scanning gun to parse the class needs to call analysisKeyEvent (KeyEvent event) in the related class, and pass in the listening event. When the corresponding event is parsed to obtain the input content, it is returned through the OnScanSuccessListener interface callback


/**
 *  Code scanning gun event parsing class  by chen
 */
public class ScanGunKeyEventHelper {
    private final static long MESSAGE_DELAY = 500;// Delay 500ms And judging whether the code scanning is completed. 
    private StringBuffer mStringBufferResult;// Scan code content 
    private boolean mCaps;// Case sensitivity 
    private final Handler mHandler;
    private final BluetoothAdapter mBluetoothAdapter;
    private final Runnable mScanningFishedRunnable;
    private OnScanSuccessListener mOnScanSuccessListener;
    private String mDeviceName;

    public ScanGunKeyEventHelper(OnScanSuccessListener onScanSuccessListener) {
        mOnScanSuccessListener = onScanSuccessListener ;
        // Get the system Bluetooth adapter management class 
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//        BluetoothDevice printerdevice = mBluetoothAdapter.getRemoteDevice("ssss");
//        BluetoothSocket btSocket = printerdevice.createRfcommSocketToServiceRecord("ssss");
        mStringBufferResult = new StringBuffer();
        mHandler = new Handler();
        mScanningFishedRunnable = new Runnable() {
            @Override
            public void run() {
                performScanSuccess();
            }
        };
    }
    /**
     *  Return the result after successful code scanning 
     */
    private void performScanSuccess() {
        String barcode = mStringBufferResult.toString();
        if (mOnScanSuccessListener != null)
            mOnScanSuccessListener.onScanSuccess(barcode);
        mStringBufferResult.setLength(0);
    }
    /**
     *  Analysis of Code Scanning Gun Event 
     * @param event
     */
    public void analysisKeyEvent(KeyEvent event) {
        int keyCode = event.getKeyCode();
        // Letter case judgment 
        checkLetterStatus(event);
        if (event.getAction() == KeyEvent.ACTION_DOWN) {

            char aChar = getInputCode(event);;

            if (aChar != 0) {
                mStringBufferResult.append(aChar);
            }
            if (keyCode == KeyEvent.KEYCODE_ENTER) {
                // If it is Enter key, return directly 
                mHandler.removeCallbacks(mScanningFishedRunnable);
                mHandler.post(mScanningFishedRunnable);
            } else {
                // Delay post If 500ms Inside, there are other events 
                mHandler.removeCallbacks(mScanningFishedRunnable);
                mHandler.postDelayed(mScanningFishedRunnable, MESSAGE_DELAY);
            }

        }
    }

    // Check shift Key 
    private void checkLetterStatus(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                // Press shift Key, representing uppercase 
                mCaps = true;
            } else {
                // Loosen shift Key for lowercase 
                mCaps = false;
            }
        }
    }
    // Get scanned content 
    private char getInputCode(KeyEvent event) {
        int keyCode = event.getKeyCode();
        char aChar;
        if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
            // Alphabet 
            aChar = (char) ((mCaps ? 'A' : 'a') + keyCode - KeyEvent.KEYCODE_A);
        } else if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
            // Figures 
            aChar = (char) ('0' + keyCode - KeyEvent.KEYCODE_0);
        } else {
            // Other symbols 
            switch (keyCode) {
                case KeyEvent.KEYCODE_PERIOD:
                    aChar = '.';
                    break;
                case KeyEvent.KEYCODE_MINUS:
                    aChar = mCaps ? '_' : '-';
                    break;
                case KeyEvent.KEYCODE_SLASH:
                    aChar = '/';
                    break;
                case KeyEvent.KEYCODE_BACKSLASH:
                    aChar = mCaps ? '|' : '\\';
                    break;
                default:
                    aChar = 0;
                    break;
            }
        }
        return aChar;
    }

    public interface OnScanSuccessListener {
        void onScanSuccess(String barcode);
    }

    public void onDestroy() {
        mHandler.removeCallbacks(mScanningFishedRunnable);
        mOnScanSuccessListener = null;
    }
    // Some mobile phones such as 3 Star, this method cannot be used 
//    private void hasScanGun() {
//        Configuration cfg = getResources().getConfiguration();
//        return cfg.keyboard != Configuration.KEYBOARD_NOKEYS;
//    }
    /**
     *  Is the scanning gun connected 
     * @return
     */
    public boolean hasScanGun() {
        if (mBluetoothAdapter == null) {
            return false;
        }
        Set<BluetoothDevice> blueDevices = mBluetoothAdapter.getBondedDevices();
        if (blueDevices == null || blueDevices.size() <= 0) {
            return false;
        }
        for (Iterator<BluetoothDevice> iterator = blueDevices.iterator(); iterator.hasNext(); ) {
            BluetoothDevice bluetoothDevice = iterator.next();

            if (bluetoothDevice.getBluetoothClass().getMajorDeviceClass() == BluetoothClass.Device.Major.PERIPHERAL) {

                mDeviceName = bluetoothDevice.getName();
                return isInputDeviceExist(mDeviceName);
            }
        }
        return false;
    }
    /**
     *  Does the input device exist 
     * @param deviceName
     * @return
     */
    private boolean isInputDeviceExist(String deviceName) {
        int[] deviceIds = InputDevice.getDeviceIds();

        for (int id : deviceIds) {
            if (InputDevice.getDevice(id).getName().equals(deviceName)) {
                return true;
            }
        }
        return false;
    }
    /**
     *  Is it a code scanning gun event ( Partial models KeyEvent Wrong name obtained )
     * @param event
     * @return
     */
    @Deprecated
    public boolean isScanGunEvent(KeyEvent event) {
        return event.getDevice().getName().equals(mDeviceName);
}


    /**
     *  Check whether Bluetooth is turned on 
     */
    public int checkBluetoothValid() {

        if(mBluetoothAdapter == null) {// Your device does not have Bluetooth functionality !
            return 1;
        }

        if(!mBluetoothAdapter.isEnabled()) {// Bluetooth device is not turned on , Please turn on this function and try again !
            return 2;
        }
        return 3;// Bluetooth works properly 
    }


}

5. Using the parsing class ScanGunKeyEventHelper in Activity

The dispatchKeyEvent method is overridden in Activity to intercept Key events.


  /**
     *  Intercept key event . Issue ScanGunKeyEventHelper
     *
     * @param event
     * @return
     */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {

        if (mScanGunKeyEventHelper.isScanGunEvent(event)) {
            mScanGunKeyEventHelper.analysisKeyEvent(event);
            return true;
        }
        return super.dispatchKeyEvent(event);
    }

Get the scan result callback, please see TestScanner for detailed code


/**
 * @author Wu JianCheng
 * @date on   2018/12/18 14:44
 *  Test the function of Bluetooth connection scanning gun 
 */
public class BleAct extends Activity implements ScanGunKeyEventHelper.OnScanSuccessListener {

    ...
    
    /**
     *  Scan result callback 
     * @param barcode
     */
    @Override
    public void onScanSuccess(String barcode) {
        showToast(barcode);
    }
    
    ...

}

Related articles: