📚 故事背景:你是一位「智能设备指挥官」
你的 Android 设备是一个「万能控制中心」,而串口设备、USB 打印机、扫码枪等外设是听你指挥的「特种部队」。今天,我将带你用代码指挥这些设备完成各种任务!
🧩 第一章:串口设备(电子秤/传感器)—— 古老而可靠的「电报机」
故事:串口就像一台老式电报机,通过
/dev/ttyS4这样的「频道」发送摩尔斯电码(二进制数据)。波特率9600是双方约定的「发报速度」。
关键代码:
java
Copy
// 电报机初始化(串口连接)
public class SerialPort {
private FileDescriptor mFd; // 电报机的通信管道
private FileInputStream mInputStream; // 收报机
private FileOutputStream mOutputStream; // 发报机
// 打开电报频道
public SerialPort(File device, int baudrate, int flags) throws IOException {
mFd = open(device.getAbsolutePath(), baudrate, flags); // JNI魔法!
mInputStream = new FileInputStream(mFd);
mOutputStream = new FileOutputStream(mFd);
}
// 加载电报解码器(本地库)
static { System.loadLibrary("serial_port"); }
private native FileDescriptor open(String path, int baudrate, int flags);
}
使用示例:
kotlin
Copy
// 1. 连接电子秤电报机
val serialPort = SerialPort(File("/dev/ttyS4"), 9600, 0)
// 2. 读取电子秤发来的重量电报
Thread {
val inputStream = serialPort.inputStream
while (true) {
val buffer = ByteArray(inputStream.available())
inputStream.read(buffer)
val weight = parseWeight(buffer) // 解析电报内容(如:01 23 = 123g)
runOnUiThread { displayWeight(weight) }
}
}.start()
// 3. 发送校准指令给电子秤
fun calibrateScale() {
val cmd = byteArrayOf(0x55, 0xAA) // 密语:开始校准!
serialPort.outputStream.write(cmd)
}
🖨️ 第二章:USB 打印机 —— 会吐纸的「魔法画师」
故事:USB 打印机是宫廷画师,Android 是国王。国王需要先颁发「御赐令牌」(USB 权限),画师才能作画。
关键步骤:
-
颁发令牌(权限声明):
xml Copy <uses-permission android:name="android.permission.USB_PERMISSION" /> <uses-feature android:name="android.hardware.usb.host" /> -
寻找画师(检测打印机):
kotlin Copy val usbManager = getSystemService(USB_SERVICE) as UsbManager usbManager.deviceList.values.forEach { device -> if (device.getInterface(0).interfaceClass == 7) { // 7=画师身份码 requestPrinterPermission(device) // 颁发令牌 } } -
发送绘画指令(ESC/POS 命令):
kotlin Copy fun printText(text: String) { val cmd = text.toByteArray(charset("GBK")) // 中文需转码 usbConnection.bulkTransfer(outEndpoint, cmd, cmd.size, 5000) } // 魔法指令示例 fun printLogo() { val cutCommand = byteArrayOf(0x1D, 0x56, 0x41) // ✂️切纸指令 usbConnection.bulkTransfer(outEndpoint, cutCommand, cutCommand.size, 5000) }
🔍 第三章:扫码枪/支付盒子 —— 会说话的「魔法水晶」
故事:扫码枪是预言水晶,扫一下商品就能念出它的「真名」(条码)。Android 只需竖起耳朵听。
监听方式:
方法一:水晶广播(全局监听)
xml
Copy
<!-- AndroidManifest.xml -->
<receiver android:name=".ScanReceiver">
<intent-filter>
<action android:name="com.scanner.ACTION_BARCODE" />
</intent-filter>
</receiver>
java
Copy
// 接收水晶预言
public class ScanReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String barcode = intent.getStringExtra("SCAN_DATA"); // 水晶念出的密码
handleBarcode(barcode);
}
}
方法二:国王亲耳听(Activity 监听)
kotlin
Copy
// 在Activity中监听水晶低语
val barcodeBuilder = StringBuilder()
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
when (keyCode) {
KeyEvent.KEYCODE_ENTER -> { // 听到「咒语结束符」
val barcode = barcodeBuilder.toString()
handleBarcode(barcode)
barcodeBuilder.clear()
return true
}
else -> { // 拼接待咒语
val char = KeyUtils.keyCodeToChar(keyCode, event.isShiftPressed)
barcodeBuilder.append(char)
}
}
return super.onKeyDown(keyCode, event)
}
避坑指南:
如果不想让水晶的咒语被「魔法输入框」(EditText)偷听,记得:xml Copy <EditText android:focusable="false" android:focusableInTouchMode="false"/>
🖱️ 第四章:键盘/鼠标 —— 忠诚的「信使鸽」
故事:USB 键盘和鼠标是信使鸽,Android 城堡会自动接收它们带来的消息。
特殊技巧:
kotlin
Copy
// 监听特殊信鸽(如ESC键)
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_ESCAPE) {
finish() // ESC键关闭当前窗口
return true
}
return super.onKeyDown(keyCode, event)
}
💾 第五章:U盘 —— 会飞的「魔法背包」
故事:U 盘是魔法师的背包,插入 USB 接口就会自动打开空间门(挂载路径)。
监听背包出现:
kotlin
Copy
val filter = IntentFilter().apply {
addAction(Intent.ACTION_MEDIA_MOUNTED) // 背包出现!
addAction(Intent.ACTION_MEDIA_UNMOUNTED) // 背包消失!
addDataScheme("file") // 重要咒语!
}
registerReceiver(usbReceiver, filter)
// 检查背包里的宝物
val usbFiles = File("/storage/usb0").listFiles()
usbFiles?.forEach { file ->
println("发现宝物:${file.name}")
}
⚔️ 终极战斗手册(避坑指南)
-
串口数据解析
不同设备有不同「方言」,需按厂商协议解析:kotlin Copy // 电子秤数据示例:01 23 45 = 123.45g fun parseWeight(data: ByteArray): Double { val str = String(data, Charsets.US_ASCII) return str.substring(2, 7).toDouble() / 100 } -
USB 设备重连
拔出后重新插入需要重新请求权限:kotlin Copy private val usbReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action == UsbManager.ACTION_USB_DEVICE_ATTACHED) { val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE) requestPrinterPermission(device) // 重新颁发令牌 } } } -
扫码枪冲突
多个输入设备时,用event.deviceId区分来源:kotlin Copy override fun onKeyEvent(event: KeyEvent): Boolean { if (event.deviceId == scannerDeviceId) { // 只处理水晶的消息 // 解析条码... } return true }
指挥官备忘录:
- 串口:
/dev/ttyS*+ 波特率 + JNI库- USB设备:权限声明 +
UsbManager+ 端点通信- 输入设备:监听
onKeyEvent或广播- 黄金法则:所有外设操作都要放在子线程!
现在,举起你的「代码魔杖」,开始指挥你的智能设备军团吧! 🧙♂️✨