您的位置:首页技术文章
文章详情页

android - 安卓app实现与蓝牙模块的数据通信,当蓝牙模块离开有效距离时与手机app断开连接,app想在断开连接时有所提示,要怎么实现

【字号: 日期:2024-08-26 14:18:32浏览:41作者:猪猪

问题描述

/**

简化蓝牙操作的工具类*/

public class BluetoothUtils {

public static final int ENABLE_BLUETOOTH = 0; // 发现蓝牙未开启发送的开启蓝牙消息public static final int DEVICE_SCAN_STARTED = 1; // 扫描设备开始时发送的消息public static final int DEVICE_SCAN_STOPPED = 2; // 扫描终止时发送的消息public static final int DEVICE_SCAN_COMPLETED = 3; // 扫描设备完成时发送的消息public static final int DEVICE_CONNECTED = 4; // 连接上设备时发送的消息public static final int DATA_SENDED = 5; // 发送数据后发送清除edittext内容的消息public static final int DATA_READED = 6; // 读取到数据后发送使适配器更新的消息public static final int CHARACTERISTIC_ACCESSIBLE = 7; // 可操作特征值时发送的消息private boolean mScanning; // 设备扫描状态的标志private byte[] readedData; // 读取到的字节数组数据private Context context;private Handler handler;private BluetoothAdapter mBleAdapter;private BluetoothGatt mBluetoothGatt;private BluetoothGattCharacteristic mCharacteristic;private DeviceListAdapter mDeviceListAdapter;private DataBuffer dataBuffer;public BluetoothUtils(Context context, Handler handler) { this.context = context; this.handler = handler;dataBuffer = new DataBuffer(4096); }public void initialize() { BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); mBleAdapter = manager.getAdapter(); mDeviceListAdapter = new DeviceListAdapter(context);}/** * 检测蓝牙开启状态,若未开启则发送开启蓝牙消息 */public void checkBluetoothEnabled() { if (mBleAdapter == null || !mBleAdapter.isEnabled()) {Message message = new Message();message.what = ENABLE_BLUETOOTH;handler.sendMessage(message); }}/** * 检测当前设备扫描的状态,若在扫描中则停止扫描 */public void checkDeviceScanning() { if (mScanning) {scanBleDevice(false); }}/** * 检测蓝牙连接状态,若已连接则断开并关闭连接 */public void checkGattConnected() { if (mBluetoothGatt != null) {if (mBluetoothGatt.connect()) { mBluetoothGatt.disconnect(); mBluetoothGatt.close();} }}/** * 扫描设备的方法,扫描按钮点击后调用,扫描持续3秒 * * @param enable 扫描方法的使能标志 */public void scanBleDevice(boolean enable) { if (enable) {handler.postDelayed(new Runnable() { @Override public void run() {mScanning = false;mBleAdapter.stopLeScan(mLeScanCallback);Message message = new Message();message.what = DEVICE_SCAN_COMPLETED;handler.sendMessage(message); }}, 5000);mScanning = true; //mBleAdapter.startLeScan(new UUID[] {UUID.fromString('0000F445-0000-1000-8000-00805F9B34FB'),UUID.fromString('0000FEE0-0000-1000-8000-00805F9B34FB')},mLeScanCallback);mBleAdapter.startLeScan(mLeScanCallback);Message message = new Message();message.what = DEVICE_SCAN_STARTED;handler.sendMessage(message); } else {mScanning = false;mBleAdapter.stopLeScan(mLeScanCallback);Message message = new Message();message.what = DEVICE_SCAN_STOPPED;handler.sendMessage(message); }}/** * 往特征值里写入数据的方法 * * @param data 字节数组类型的数据 */public void writeData(byte[] data) { if (mBluetoothGatt != null) {if (mBluetoothGatt.connect() && mCharacteristic != null &&data != null) { mCharacteristic.setValue(data); mBluetoothGatt.writeCharacteristic(mCharacteristic);} }}/** * 创建一个新的设备列表对话框 */public void creatDeviceListDialog() { if (mDeviceListAdapter.getCount() > 0) {new AlertDialog.Builder(context).setCancelable(true) .setAdapter(mDeviceListAdapter, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) { BluetoothDevice device = mDeviceListAdapter.getDevice(which); mBluetoothGatt = device.connectGatt(context, false, mGattCallback);} }).show(); }}/** * 开启特征值的notification,然后才能读取数据 */public void setCharacteristicNotification() { String clientUuid = '00002902-0000-1000-8000-00805f9b34fb'; mBluetoothGatt.setCharacteristicNotification(mCharacteristic, true); BluetoothGattDescriptor descriptor = mCharacteristic. getDescriptor(UUID.fromString(clientUuid)); descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); mBluetoothGatt.writeDescriptor(descriptor);}/** * 字节数组转化为标准的16进制字符串 * * @param bytes 字节数组数据 * @return 字符串 */public String bytesToString(byte[] bytes) { final char[] hexArray = '0123456789ABCDEF'.toCharArray(); char[] hexChars = new char[bytes.length * 2]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) {int v = bytes[i] & 0xFF;hexChars[i * 2] = hexArray[v >>> 4];hexChars[i * 2 + 1] = hexArray[v & 0x0F];sb.append(hexChars[i * 2]);sb.append(hexChars[i * 2 + 1]);sb.append(’ ’); } return sb.toString();}/** * 将字符串转为16进制值的字节数组 * * @param s 字符串数据 * @return buf 字节数组 */public byte[] stringToBytes(String s) { byte[] buf = new byte[s.length() / 2]; for (int i = 0; i < buf.length; i++) {try { buf[i] = (byte) Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16);} catch (NumberFormatException e) { e.printStackTrace();} } return buf;}/** * Ascii编码的字节数组转化为对应的字符串 * * @param bytes 字节数组 * @return 字符串 */public String asciiToString(byte[] bytes) { char[] buf = new char[bytes.length]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < buf.length; i++) {buf[i] = (char) bytes[i];sb.append(buf[i]); } return sb.toString();}/** * 变换文本的方法,有动画效果 * * @param textView 目标文本view对象 * @param convertTextId 变换后的文本resId */public void convertText(final TextView textView, final int convertTextId) { final Animation scaleIn = AnimationUtils.loadAnimation(context, R.anim.text_scale_in); Animation scaleOut = AnimationUtils.loadAnimation(context, R.anim.text_scale_out); scaleOut.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) { textView.setText(convertTextId); textView.startAnimation(scaleIn);}@Overridepublic void onAnimationRepeat(Animation animation) {} }); textView.startAnimation(scaleOut);}/** * 获取已连接设备的设备名 * * @return 字符串形式的设备名 */public String getDeviceName() { return mBluetoothGatt.getDevice().getName();}/** * 获取已读取的数据 * * @return 字节数组数据 */public byte[] getReadedData() { return readedData;}/** * 获取已读取的数据长度 * * @return */public int getDataLen() { return dataBuffer.getSize();}/** * 获取已读取的数据 * * @return */public int getData(byte[] data_out,int len) { return dataBuffer.dequeue(data_out, len);}

/** * 连接Gatt之后的回调 */private BluetoothGattCallback mGattCallback =new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {if (newState == BluetoothProfile.STATE_CONNECTED) { Message message = new Message(); message.what = DEVICE_CONNECTED; handler.sendMessage(message); mDeviceListAdapter.clear(); gatt.discoverServices();} } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {if (characteristic != null) { dataBuffer.enqueue(characteristic.getValue(), characteristic.getValue().length); Message message = new Message(); message.what = DATA_READED; handler.sendMessage(message);} } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {if (status == BluetoothGatt.GATT_SUCCESS) { Message message = new Message(); message.what = DATA_SENDED; handler.sendMessage(message);} } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) { // 得到目标特征值 String serviceUuid = '0000fee0-0000-1000-8000-00805f9b34fb'; String characterUuid = '0000fee1-0000-1000-8000-00805f9b34fb'; BluetoothGattService service = gatt.getService(UUID .fromString(serviceUuid)); mCharacteristic = service.getCharacteristic(UUID .fromString(characterUuid)); //开启通知 setCharacteristicNotification(); Message message = new Message(); message.what = CHARACTERISTIC_ACCESSIBLE; handler.sendMessage(message);} } };/** * 蓝牙扫描时的回调 */private BluetoothAdapter.LeScanCallback mLeScanCallback =new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {String buf = bytesToString(scanRecord);System.out.println('BluetoothUtils.enclosing_method():'+device.getName()+'nscanRecord'+buf+'rssi:'+rssi);//if ('E0 FE'.equals(buf.substring(0, buf.length()))) { mDeviceListAdapter.addDevice(device); mDeviceListAdapter.notifyDataSetChanged();} }};

}如上是蓝牙操作的工具类,想在蓝牙模块与app断开连接时,app那边有提示大概怎么实现

列表项目

问题解答

回答1:

android - 安卓app实现与蓝牙模块的数据通信,当蓝牙模块离开有效距离时与手机app断开连接,app想在断开连接时有所提示,要怎么实现这里不就是连接状态的回调吗?

else if (newState == BluetoothProfile.STATE_DISCONNECTED) { TODO 这里做断开以后的逻辑}