Discover Printers:

Before starting this tutorial, it is important to note that the SDK was not designed to discover, connect, print, and disconnect all at once. The printer itself will still struggle to receive and send data this quickly.

Example: It is not recommended to design an app with a single button labeled "Print" where the app would discover, connect, print, and then disconnect on the button click.

Requesting Permissions:

In order to discover nearby printers, the user must approve the required permissions:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
    //Build.VERSION_CODES.S is SDK Version 31. When version 31 was released, the required bluetooth permissions changed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH}, 0);
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH}, 0);
  • This should prompt the user only on the initial opening of the application.
    • If the user does not allow permissions when prompted, they can always go into the settings app to allow them later. However, the user will never be able to discover printers without approving these permissions.

Implementing Discovery:

  • Create a new PrinterDiscoveryImpl which takes the app context:
List<PrinterDiscoveryListener> printerDiscoveryListeners = new ArrayList<>();
PrinterDiscovery printerDiscovery = PrinterDiscoveryFactory.getPrinterDiscovery(context.getApplicationContext(), printerDiscoveryListeners);
  • Override life cycle system methods in
    • Must do this for the scan to continue when navigating UI.
    • The following example starts ALL printer discovery scans when the app is opened and pauses them when the app is backgrounded.
protected void onResume() {
    if(printerDiscovery != null) {

protected void onPause(){
    if(printerDiscovery != null)

protected void onDestroy(){
    if(printerDiscovery != null)
  • Start discovering nearby printers:

    • To start discovering devices compatible with Wi-Fi, call:
      • printerDiscovery.startWifiPrinterDiscovery();
    • To start discovering Bluetooth Classic devices, call:
      • printerDiscovery.startBluetoothPrinterDiscovery(false);
      • If the parameter is set to true, it will only discover printers already paired to the mobile device.
      • If the parameter is set to false, it will return printers paired to the mobile device AND search nearby for other printers. (If a printer is both already paired and turned on nearby, it will be found twice).
    • To start discovering Bluetooth Low Energy devices, call:
      • printerDiscovery.startBlePrinterDiscovery()
  • To stop all discovery processes:

    • printerDiscovery.stopPrinterDiscovery()


If customers are using an M611 Latimer, do not call "printerDiscovery.startBluetoothPrinterDiscovery()". This is because the M611 firmware has a bug where it can be discovered as a Bluetooth Classic device even though it only supports a Bluetooth Low Energy connection. M611's bought after March 2023 are most likely M611 Latimer's. This can be tested by downloading the Brady Express Labels application and attempting to connect to it via Bluetooth Low Energy.

Implementing PrinterDiscoveryListener

In order to "catch" discovered printers, implement the SDK's PrinterDiscoveryListener in your UI's class header.

public class MainActivity implements PrinterDiscoveryListener {

Implementing this interface will force you to add its respective methods which are as follows:

  • printerDiscovered (triggers when a printer is found and gives you the object).
  • printerDiscoveryStarted (triggers when discovery scan starts).
  • printerDiscoveryStopped (triggers when discovery scan stops).