The Android device acquires the scanning content of the code scanning gun
- 2021-12-21 05:01:49
- OfStack
Bar code scanning gun can be seen everywhere now, which can scan the bar code content quickly, which is faster than any mobile phone camera scanning code, not 1:00 or 2:00.
In order to save costs, the code scanning gun can be directly connected to android or other devices through Bluetooth.
So how does android device get scanned content through Bluetooth?
1. Bluetooth pairing, connecting devices
Open the system settings, find Bluetooth, open the code scanning gun, and pair the code scanning gun equipment. Enter a fixed pairing code, which is written in the instruction manual of a code scanning gun. After the pairing is completed, the display device is connected. Just ok.
2. Configure permissions in 2. AndroidManifest
Add Bluetooth permissions to the AndroidManifest. xml file in the android project.
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
3. Detect the connection status of the code scanning gun
Generally speaking, the code scanning gun equipment is also equivalent to the common external input equipment type and external keyboard.
My code scanning gun device returns the following Bluetooth type.
BluetoothClass.Device.Major.PERIPHERAL
Generally speaking, the information of our code scanning gun equipment can be obtained in the following way.
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) {
//TODO Acquiring code scanning gun equipment information
}
}
In the development process, it is necessary to judge whether the equipment is connected normally in real time.
mBluetoothAdapter.getBondedDevices()
This method can only determine whether the device is paired and bound. But binding does not represent a connection, so you can only give up.
public List getConnectedDevices (int profile)
public int getConnectionState (BluetoothDevice device, int profile)
Then I tried these two methods, which are available, but the device sdk must be required > 18, that is, android version 4.3 or above.
Later, I turned to think that since the code scanning gun is also an input device, we can start with the status detection of different Bluetooth devices and start with the detection of input devices instead. So,
private void hasScanGun() {
Configuration cfg = getResources().getConfiguration();
return cfg.keyboard != Configuration.KEYBOARD_NOKEYS;
}
Done.
4. Get the scanning content of the code scanning gun
Scanning gun, since it is an external input device, it is natural for us to start with KeyEvent.
Event resolution class
/**
* Code scanning gun event parsing class
*/
public class ScanGunKeyEventHelper {
// Delay 500ms And judging whether the code scanning is completed.
private final static long MESSAGE_DELAY = 500;
// Scan code content
private StringBuffer mStringBufferResult = new StringBuffer();
// Case sensitivity
private boolean mCaps;
private OnScanSuccessListener mOnScanSuccessListener;
private Handler mHandler = new Handler();
private final Runnable mScanningFishedRunnable = new Runnable() {
@Override
public void run() {
performScanSuccess();
}
};
// Return scan results
private void performScanSuccess() {
String barcode = mStringBufferResult.toString();
if (mOnScanSuccessListener != null)
mOnScanSuccessListener.onScanSuccess(barcode);
mStringBufferResult.setLength(0);
}
//key Event handling
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 {
public void onScanSuccess(String barcode);
}
public void setOnBarCodeCatchListener(OnScanSuccessListener onScanSuccessListener) {
mOnScanSuccessListener = onScanSuccessListener;
}
public void onDestroy() {
mHandler.removeCallbacks(mScanningFishedRunnable);
mOnScanSuccessListener = null;
}
}
The dispatchKeyEvent method is overridden in Activity to intercept Key events.
/**
* Activity Intercept key event . Issue ScanGunKeyEventHelper
*
* @param event
* @return
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (isScanGunEvent(event)) {
mScanGunKeyEventHelper.analysisKeyEvent(event);
return true;
}
return super.dispatchKeyEvent(event);
}
/**
* Display scanned content
* @param barcode Bar code
*/
@Override
public void onScanSuccess(String barcode) {
//TODO Display scanned content
}
For detailed codes, please refer to: https://github.com/czhzero/scangon
Note:
1. Some models can't judge the external keyboard information, such as 3 stars.
private void hasScanGun() {
Configuration cfg = getResources().getConfiguration();
return cfg.keyboard != Configuration.KEYBOARD_NOKEYS;
}
The return value of 3-star mobile phone cfg.keyboard is equal to Configuration.KEYBOARD_NOKEYS.
Therefore, for better compatibility, the following methods can be adopted
/**
* Judge whether the code scanning gun has been connected
* @return
*/
protected boolean hasScanGun() {
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) {
return isInputDeviceUsed(bluetoothDevice.getName());
}
}
return false;
}
private boolean isInputDeviceUsed(String deviceName) {
int[] deviceIds = InputDevice.getDeviceIds();
for (int id : deviceIds) {
if (InputDevice.getDevice(id).getName().equals(deviceName)) {
return true;
}
}
return false;
}