[Phần 2] Kết nối máy in BBPOS SimplyPrint với điện thoại Android qua Bluetooth

Xin chào mọi người trong phần trước mình đã hướng dẫn các bạn kết nối điện thoại android với các máy in phổ thông nhưng còn đối với một số dòng máy in đặc thù thì phải sử dụng thư viện riêng tùy theo từng dòng máy, hôm nay mình sẽ hướng dẫn kết nối và in thử trên máy in BBPOS SimplyPrint


- Các chức năng yêu cầu:
  1. Có thể bật bluetooth nếu phát hiện bluetooth chưa bật
  2. Quét ra các thiết bị đã từng kết nối, chọn vào máy in thì tự động kết nối
  3. Quét ra các thiết bị chưa kết nối bao giờ, chọn vào máy in nào thì tự động kết nối
- Lưu ý: các chức năng trên đều diễn ra trong ứng dụng, người dùng không phải thao tác trong phần cài đặt bluetooth

1. Thư viện để sử lý kết nối và in của bbpos cung cấp: simplyprintapi-android-1.4.0.jar
Thêm thư viện này vào đương dẫn trong project: "Tên project"\app\libs
Trong build.gradle (trong thư mục app) thêm doạn sau:
implementation files('libs/simplyprintapi-android-1.4.0.jar')
implementation 'commons-lang:commons-lang:2.6'
implementation 'org.apache.commons:commons-lang3:3.6'

2. Xin cấp các quyền cần thiết trong AndroidManifest.xml
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- Đối với Android từ 6.0 trở lên phải xin cấp quyền bằng code:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    mPermissionBluetooth = false;
    if (requestCode == 1) {
        if (grantResults.length > 0) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    mPermissionBluetooth = false;
                    Toast.makeText(this, "Cấp quyền thất bại", Toast.LENGTH_SHORT).show();
                    return;
                }
            }
            mPermissionBluetooth = true;
            bluetoothSetup();
            Toast.makeText(this, "Cấp quyền thành công", Toast.LENGTH_SHORT).show();
        }
    }
}

public void initPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};

        if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mPermissionBluetooth = true;
            } else {
                requestPermissions(permissions, 1);
            }
        } else {
            requestPermissions(permissions, 1);
        }
    } else        mPermissionBluetooth = true;
}
3. ReceiptUtility cấu hình các nội dung cần in như:
- In hình ảnh
- In chuỗi
- Căn chỉnh bên trái, phải, giữa
- Kích thước, kiểu chữ,... vvv

4. PrintManager cấu hình kết nối máy in, quản lý các luồng kết nối và in
- Gọi hàm này để quét các máy in và bắt sự kiện kết nối đến máy in được chọn:
public void selectSimplyPrinter() {
    simplyPrintController = new SimplyPrintController(context, new SimplyConnection());

    dialogSelectPrinter = new DialogSelectPrinter(context, new DialogSelectPrinter.OnItemSelected() {
        @Override
        public void onItemSelected(BluetoothDevice bluetoothDevice) {
            simplyPrintController.startBTv2(bluetoothDevice);
            dialogSelectPrinter.dismiss();
        }
    });
    dialogSelectPrinter.show();
}
- Class SimplyConnection kết bắt sự kiện kết nối thành công hoặc thất bại, hủy kết nối reset connect,... vvv
private class SimplyConnection implements SimplyPrintController.SimplyPrintControllerListener {
    @Override
    public void onBTv2Detected() {
        Toast.makeText(context, "onBTv2Detected", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv2DeviceListRefresh(List<BluetoothDevice> foundDevices) {
        Toast.makeText(context, "onBTv2DeviceListRefresh", Toast.LENGTH_LONG).show();
        foundDevice = foundDevices;
        if (arrayAdapter != null) {
            arrayAdapter.clear();
            for (int i = 0; i < foundDevices.size(); ++i) {
                arrayAdapter.add(foundDevices.get(i).getName());
            }
            arrayAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onBTv2Connected(BluetoothDevice bluetoothDevice) {
        Toast.makeText(context, "Kết nối thành công", Toast.LENGTH_LONG).show();
        isBluetoothConnected = true;
        isBtv2Connected = true;
    }

    @Override
    public void onBTv2Disconnected() {
        isBluetoothConnected = false;
        isBtv2Connected = false;
        Toast.makeText(context, "Printer is disconnected", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv2ScanStopped() {
        isBtv2Connected = false;
        Toast.makeText(context, "onBTv2ScanStopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv2ScanTimeout() {
        isBtv2Connected = false;
        Toast.makeText(context, "onBTv2ScanTimeout", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv4DeviceListRefresh(List<BluetoothDevice> foundDevices) {
        foundDevice = foundDevices;
        if (arrayAdapter != null) {
            arrayAdapter.clear();
            for (int i = 0; i < foundDevices.size(); ++i) {
                arrayAdapter.add(foundDevices.get(i).getName());
            }
            arrayAdapter.notifyDataSetChanged();
        }

        Toast.makeText(context, "onBTv4DeviceListRefresh", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv4Connected() {
        Toast.makeText(context, "onBTv4Connected", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv4Disconnected() {
        Toast.makeText(context, "onBTv4Disconnected", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv4ScanStopped() {
        Toast.makeText(context, "onBTv4ScanStopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBTv4ScanTimeout() {
        Toast.makeText(context, "onBTv4ScanTimeout", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onReturnDeviceInfo(Hashtable<String, String> deviceInfoTable) {
        String productId = deviceInfoTable.get("productId");
        String firmwareVersion = deviceInfoTable.get("firmwareVersion");
        String bootloaderVersion = deviceInfoTable.get("bootloaderVersion");
        String hardwareVersion = deviceInfoTable.get("hardwareVersion");
        String isUsbConnected = deviceInfoTable.get("isUsbConnected");
        String isCharging = deviceInfoTable.get("isCharging");
        String batteryLevel = deviceInfoTable.get("batteryLevel");
    }

    @Override
    public void onReturnPrinterResult(SimplyPrintController.PrinterResult printerResult) {
        if (printerResult == SimplyPrintController.PrinterResult.SUCCESS) {
            Toast.makeText(context, "SUCCESS", Toast.LENGTH_LONG).show();
        } else if (printerResult == SimplyPrintController.PrinterResult.NO_PAPER) {
            Toast.makeText(context, "NO_PAPER", Toast.LENGTH_LONG).show();
        } else if (printerResult == SimplyPrintController.PrinterResult.WRONG_CMD) {
            Toast.makeText(context, "WRONG_CMD", Toast.LENGTH_LONG).show();
        } else if (printerResult == SimplyPrintController.PrinterResult.OVERHEAT) {
            Toast.makeText(context, "OVERHEAT", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onReturnGetDarknessResult(int value) {
    }

    @Override
    public void onReturnSetDarknessResult(boolean isSuccess) {
        if (isSuccess) {
        } else {
        }
    }

    @Override
    public void onRequestPrinterData(int index, boolean isReprint) {
        if (receipts.size() != 0) {
            simplyPrintController.sendPrinterData(receipts.get(index));
            if (isReprint) {
                Toast.makeText(context, "onRequestPrinterData", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "sendPrinterData", Toast.LENGTH_LONG).show();
            }
        }
    }

    @Override
    public void onPrinterOperationEnd() {
        Toast.makeText(context, "onPrinterOperationEnd", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onBatteryLow(SimplyPrintController.BatteryStatus batteryStatus) {
        if (batteryStatus == SimplyPrintController.BatteryStatus.LOW) {
        } else if (batteryStatus == SimplyPrintController.BatteryStatus.CRITICALLY_LOW) {
        }
    }

    @Override
    public void onBTv2DeviceNotFound() {
        Toast.makeText(context, "onBTv2DeviceNotFound", Toast.LENGTH_LONG).show();
    }


    @Override
    public void onError(SimplyPrintController.Error errorState) {
        if (receipts != null)
            receipts.clear();

        if (errorState == SimplyPrintController.Error.UNKNOWN) {
            Toast.makeText(context, "Có lỗi xảy ra khi kết nối máy in", Toast.LENGTH_LONG).show();
        } else if (errorState == SimplyPrintController.Error.CMD_NOT_AVAILABLE) {
        } else if (errorState == SimplyPrintController.Error.TIMEOUT) {
            Toast.makeText(context, "Hết thời gian kết nối", Toast.LENGTH_LONG).show();
        } else if (errorState == SimplyPrintController.Error.DEVICE_BUSY) {
            Toast.makeText(context, "Lỗi. Máy in đang kết nối với thiết bị khác", Toast.LENGTH_LONG).show();
        } else if (errorState == SimplyPrintController.Error.INPUT_OUT_OF_RANGE) {
        } else if (errorState == SimplyPrintController.Error.INPUT_INVALID) {
        } else if (errorState == SimplyPrintController.Error.CRC_ERROR) {
        } else if (errorState == SimplyPrintController.Error.FAIL_TO_START_BTV2) {
            Toast.makeText(context, "Không thể kết nối máy in", Toast.LENGTH_LONG).show();
        } else if (errorState == SimplyPrintController.Error.COMM_LINK_UNINITIALIZED) {
        }
    }
}
5. Layout activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:card_view="http://schemas.android.com/apk/res-auto"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">

    <LinearLayout        android:id="@+id/layout_content"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">

        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:text="Simply Print"            android:textSize="20sp"            android:textStyle="bold" />

        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:textSize="20sp"            android:text="Enter Your Message : " />

        <EditText            android:id="@+id/txtMessage"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:lines="4"            android:gravity="top"            android:hint="Print text" />

        <Button            android:id="@+id/Scan"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginTop="10dp"            android:text="Scan"></Button>

        <Button            android:id="@+id/btnPrint"            android:layout_width="300dp"            android:layout_height="wrap_content"            android:layout_centerHorizontal="true"            android:layout_gravity="center"            android:layout_marginTop="5dip"            android:text="Print Message"            android:textColor="#fff" />
        <Button            android:id="@+id/btnBill"            android:layout_width="300dp"            android:layout_height="wrap_content"            android:layout_marginTop="5dip"            android:layout_gravity="center"            android:textColor="#fff"            android:layout_centerHorizontal="true"            android:text="Print Bill" />
    </LinearLayout>
</RelativeLayout>
6. MainActivity
- Thiết lập các đối tượng cơ bản để sử dụng bluetooth:
public void bluetoothSetup() {
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter == null) {
        // Device does not support Bluetooth        Toast.makeText(MainActivity.this, "Bluetooth not supported!!", Toast.LENGTH_SHORT).show();
        return;
    }

    if (!mBluetoothAdapter.isEnabled()) {
        //nếu chưa bật bluetooth thì gọi activity bật bluetooth        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        return;
    }

    if (!printManager.isBluetoothConnected) {
        printManager.selectSimplyPrinter();
    } else if (printManager.isBtv2Connected) {
        printManager.printerSimply();
    }
}
- Quét thiết bị xung quanh:
btnScan.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mPermissionBluetooth) {
            bluetoothSetup();
        }
    }
});
- In thử dome:
btnPrint.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mPermissionBluetooth) {
            if (!printManager.isBluetoothConnected) {
                printManager.selectSimplyPrinter();
            } else if (printManager.isBtv2Connected) {
                printManager.printerSimply();
            }
        }
    }
});
 

Source code: https://drive.google.com/file/d/1jeWbjGYW4aZCwBV4ajbg8spgw21SA6Rh/view?usp=sharing
Xem thêm: [Phần 1] Kết nối máy in Pos với điện thoại Android qua Bluetooth

Không có nhận xét nào

Được tạo bởi Blogger.