I'm mantaining an app that runs on an Android 6.0 tablet that uses a Zebra iMZ220 bluetooth printer. The app requires the printer to be paired to the tablet, of course.
From time to time, the printer appears to receive a new pairing request from the tablet to which it is already paired, with the end result of breaking the bond.
I've been unable to determine the exact cause of it, for there are no errors in the log and it appears to happen randomly.
I've found these lines which I think is supposed to pair the printer:
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
in the sequence
String printerMac = settings.getString("printerMac","");
if (!stampante.isEmpty()) {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(stampante);
try {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
Could it, for some reason, remove the bond on the printer even though it is supposed to do the opposite?
I couldn't reproduce this error on a Android 8 device.
From my experience (since i am also developing and maintaining an app that connects to a bluetooth printer) the pairing between the device and the bluetooth device can sometimes be lost although it is really rare. It is a bug that spreads amongst various devices and Android versions.
What i ended up doing is accept the possibility that it might sometime happen and implement a broadcast receiver to be notified that the pairing has been lost. At that time i create the bond again programmatically and also connect the printer.
When trying to create the bond, a default dialog will appear for the user to input the PIN the printer uses.However, since i know the PIN, i input this PIN progrmmatically so the dialog just appears for a split second and then dissapears.
After months battling with this issue this ended up to be the most elegant solution i could find.Hope it helps you as well.
In onCreate
create the filter and register the receiver:
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(mReceiver, filter);
Method to call when you want to pair with the device:
private void pairDevice(BluetoothDevice device) {
try {
//Log.d("AutoPairing", "Start Pairing... with: " + device.getName());
device.createBond();
Log.d("AutoPairing", "Pairing finished.");
} catch (Exception e) {
Log.e("AutoPairing", e.getMessage());
}
}
Broadcast Receiver :
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
}else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
}else if (BluetoothDevice.ACTION_FOUND.equals(action)){
}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
}else if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
try {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If you want to auto_insert the pin, uncomment the following lines
//String PinNew = "HereIsThePinThePrinterUses";
//device.setPin(PinNew.getBytes());
} catch (Exception e) {
Log.e("AutoPairing", "Error occurs when trying to auto pair");
e.printStackTrace();
}
}else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == 12) {
// Pairing was succesful. Do what you would normally do after that. Perhaps connect the printer now.
} else {
// Pairing was unsuccesful. **This is also what get's triggered when the pairing is getting lost**. Let's pair the device then.
pairDevice(device);
}
}
}
};
Hope i am not forgetting something.
PM: All those empty if statements
are there in case you want to connect the printer as well. If you do it some other way then you can delete them and remove those actions from the filter.