本文档针对特定Android开发板-Pad-整理。Pad中集成了一个蓝牙Mesh模块;Pad默认开放了蓝牙广播,名称为“UART”。
新安装的蓝牙模块在Android系统中映射为一个串口文件,所以操作这个蓝牙模块转变为对串口的操作,形式上就是读和写。
一.Android板
1.依赖
这里使用了一个第三方库。
1 2 3 4 |
dependencies { implementation "com.deemons.serialport:serialport:1.2.0" } |
2.必须的root权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
private boolean requestRootPermission() { Process process = null; DataOutputStream os = null; try { String cmd = "chmod 777 /dev/ttyS4"; // 目标串口文件 process = Runtime.getRuntime().exec("su"); // 切换到root帐号 os = new DataOutputStream(process.getOutputStream()); os.writeBytes(cmd + "\n"); os.writeBytes("exit\n"); os.flush(); process.waitFor(); } catch (Exception e) { return false; } finally { try { if (os != null) { os.close(); } process.destroy(); } catch (Exception e) { } } return true; } |
3.初始化串口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
try { SerialPort.setSuPath("/system/bin/su"); // root文件路径 //SerialPortFinder serialPortFinder = new SerialPortFinder(); //String[] allDevices = serialPortFinder.getAllDevices(); //String[] allDevicesPath = serialPortFinder.getAllDevicesPath(); // //for (int i = 0; i < allDevices.length; i++) { // String device1 = allDevices[i]; // Log.e("ard", "设备:" + device1); //} //for (int i = 0; i < allDevicesPath.length; i++) { // String path = allDevicesPath[i]; // Log.e("ard", "Path:" + path); //} File device = new File("/dev/ttyS4");// 对应特定的蓝牙串口设备文件 int baudRate = 115200; // 波特率 int parity = 0; // 奇偶校验,0 None(默认); 1 Odd; 2 Even int dataBits = 8; // 数据位,5 ~ 8 (默认8) int stopBit = 1; // 停止位,1 或 2 (默认 1) int flags = 0; // 标记 0(默认) serialPort = new SerialPort(device, baudRate, parity, dataBits, stopBit, flags); inputStream = serialPort.getInputStream(); // 读串口的通道 outputStream = serialPort.getOutputStream(); // 写串口的通道 } catch (IOException e) { e.printStackTrace(); Log.e("ard", "IOException:" + e.getMessage()); } |
4.向串口写数据-写给蓝牙
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
try { String string = messageEditText.getText().toString(); if (!TextUtils.isEmpty(string)) { string = string.trim(); } else { string = "123456"; } byte[] bytes = hexToByteArray(string2HexString(string)); // 目标设备收到这个bytes,先转为16进制字符串,再从16进制转为字符串 bytes = hexToByteArray(string); // 这里要求string即一个16进制字符串。每个元素取值为0-f。 outputStream.write(bytes); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); Log.e("ard", "IOException:" + e.getMessage()); } |
5.从串口读数据-接收蓝牙收到的消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
try { while (!isDestroyed()) { byte[] buffer = new byte[64]; if (inputStream == null) return; int size = inputStream.read(buffer); if (size > 0) { byte[] bRec = new byte[size]; for (int i = 0; i < size; i++) { byte bf = buffer[i]; bRec[i] = bf; } String hex = bytesToHex(bRec); Log.e("ard", "通过串口收到蓝牙消息:" + hex); } } Log.e("ard", "recordRunalbe结束"); } catch (IOException e) { e.printStackTrace(); Log.e("ard", "IOException:" + e.getMessage()); } |
6.辅助函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
private String string2HexString(String targert) { return strTo16(string2Unicode(targert)); } /** * 字符串转换unicode */ private String string2Unicode(String string) { StringBuffer unicode = new StringBuffer(); for (int i = 0; i < string.length(); i++) { // 取出每一个字符 char c = string.charAt(i); // 转换为unicode unicode.append("\\u" + Integer.toHexString(c)); } return unicode.toString(); } /** * 字符串转化成为16进制字符串 */ private String strTo16(String s) { String str = ""; for (int i = 0; i < s.length(); i++) { int ch = (int) s.charAt(i); String s4 = Integer.toHexString(ch); str = str + s4; } return str; } private byte[] hexToByteArray(String inHex) { int hexlen = inHex.length(); byte[] result; if (hexlen % 2 == 1) { //奇数 hexlen++; result = new byte[(hexlen / 2)]; inHex = "0" + inHex; } else { //偶数 result = new byte[(hexlen / 2)]; } int j = 0; for (int i = 0; i < hexlen; i += 2) { result[j] = (byte) Integer.parseInt((inHex.substring(i, i + 2)), 16); j++; } return result; } private String bytesToHex(byte[] bytes) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() < 2) { sb.append(0); } sb.append(hex); } return sb.toString(); } |
二.手机
手机可以使用原生api连接“UART”,获取其Service(00000001)和此Service下的Characteristic(00000002)及Characteristic(00000003)。对蓝牙的写操作在00000002上,获取蓝牙的消息须打开00000003的Descriptor(00002902)的通知权限。
1 2 3 4 5 |
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); boolean b = descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); boolean b1 = currentBluetoothGatt.writeDescriptor(descriptor); currentBluetoothGatt.setCharacteristicNotification(characteristic, true); |
向Android板发收消息同之前的手环操作。可参考http://www.gaohaiyan.com/2256.html
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/2259.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设