在 Android 开发中,通过蓝牙连接打印机进行打印是一种常见的场景。下面是一个更详细的示例,它将引导你如何通过蓝牙实现打印功能。
前提条件
打印机支持蓝牙通信。
Android 设备具备蓝牙功能并已开启。
打印机的 SDK 或 API 文档(获取打印机制造商提供的 SDK 和相应的文档)。
- 添加必要的权限
首先,在 AndroidManifest.xml 文件中添加访问蓝牙的权限。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<application
... >
</application>
</manifest>
- 启用蓝牙并扫描设备
MainActivity.java
package com.example.myapp;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter bluetoothAdapter;
private BluetoothDevice bluetoothDevice;
private BluetoothSocket bluetoothSocket;
private OutputStream outputStream;
private Button printButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化蓝牙适配器
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
finish();
return;
}
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
scanBluetoothDevices();
}
printButton = findViewById(R.id.print_button);
printButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
printLabel();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
scanBluetoothDevices();
} else {
Toast.makeText(this, "需要启用蓝牙来打印标签", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void scanBluetoothDevices() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
Log.d(TAG, "Paired Device: " + device.getName() + ", Address: " + device.getAddress());
if (device.getName().equals("PrinterName") || device.getAddress().equals("00:11:22:33:44:55")) {
bluetoothDevice = device;
break;
}
}
}
if (bluetoothDevice != null) {
connectToPrinter();
} else {
Toast.makeText(this, "未找到已配对的打印机", Toast.LENGTH_SHORT).show();
}
}
private void connectToPrinter() {
try {
UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
bluetoothSocket.connect();
outputStream = bluetoothSocket.getOutputStream();
Toast.makeText(this, "连接到打印机成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Log.e(TAG, "无法连接到打印机", e);
Toast.makeText(this, "无法连接到打印机", Toast.LENGTH_SHORT).show();
}
}
private void printLabel() {
if (outputStream == null) {
Toast.makeText(this, "还未连接到打印机", Toast.LENGTH_SHORT).show();
return;
}
try {
String labelData = "打印标签内容"; // 根据打印机的协议构造标签内容
outputStream.write(labelData.getBytes());
outputStream.flush();
Toast.makeText(this, "打印成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Log.e(TAG, "打印失败", e);
Toast.makeText(this, "打印失败", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
if (outputStream != null) {
outputStream.close();
}
if (bluetoothSocket != null) {
bluetoothSocket.close();
}
} catch (IOException e) {
Log.e(TAG, "关闭资源失败", e);
}
}
}
- 打印布局文件
确保你有一个简单的布局文件,比如 activity_main.xml,包含一个按钮用于触发打印操作。
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<Button
android:id="@+id/print_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打印标签" />
</LinearLayout>
- 错误和异常处理
为了确保应用的健壮性和用户体验,需要处理各种可能的错误和异常情况。
蓝牙不支持或未开启:
提示用户设备不支持蓝牙或要求用户开启蓝牙。
连接失败:
提示用户连接失败,并提供重试选项。
打印失败:
提示用户打印失败,并提供重试选项。
-
注意事项
打印机协议:不同的打印机可能使用不同的协议来接收和解析打印数据。请确保根据打印机的 SDK 或文档构造正确的打印命令。
设备配对:假设打印机已与 Android 设备配对。如果未配对,请先手动在蓝牙设置中进行配对。
错误处理:添加适当的错误处理逻辑,例如重新连接尝试、权限检查等。
权限问题:如果你的应用是针对 Android 12 或更高版本,还需要动态请求 BLUETOOTH_SCAN 和 BLUETOOTH_CONNECT 权限。
通过这些步骤,你就可以在 Android 应用中实现蓝牙打印功能。根据具体需求,还可以进一步增强用户界面和错误处理逻辑。