From 0f9c8c7329a1dcc7440f2cccaca5d353b130d08e Mon Sep 17 00:00:00 2001 From: fengjignqi <15192412330@163.com> Date: Thu, 4 Jun 2026 08:49:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=99=84=E8=BF=91=E8=93=9D?= =?UTF-8?q?=E7=89=99=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 + .../water/device/AddDeviceActivity_copy.java | 181 +++++++++++++++++- .../utils/manager/WaterDeviceManager.java | 107 +++++++++-- 3 files changed, 269 insertions(+), 21 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 601b418..87a7fa2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -230,6 +230,8 @@ dependencies { implementation 'no.nordicsemi.android.support.v18:scanner:1.6.0' //蓝牙通讯 implementation 'no.nordicsemi.android:ble:2.11.0' + //espressif官方sdk,用于esp固件的扫描,配网等。 + implementation 'com.github.espressif:esp-idf-provisioning-android:lib-2.2.3' } diff --git a/app/src/main/java/com/ckkj/water/device/AddDeviceActivity_copy.java b/app/src/main/java/com/ckkj/water/device/AddDeviceActivity_copy.java index cd0cbc1..5440073 100644 --- a/app/src/main/java/com/ckkj/water/device/AddDeviceActivity_copy.java +++ b/app/src/main/java/com/ckkj/water/device/AddDeviceActivity_copy.java @@ -41,6 +41,7 @@ import com.ckkj.water.index.entity.WaterDeviceEntity; import com.ckkj.water.network.BaseBean; import com.ckkj.water.utils.manager.ActivityManager; import com.ckkj.water.utils.manager.ThemeManager; +import com.ckkj.water.utils.manager.WaterDeviceManager; import com.ckkj.water.utils.show.ToastUtil; import com.gyf.immersionbar.ImmersionBar; import com.maning.mlkitscanner.scan.MNScanManager; @@ -48,12 +49,14 @@ import com.maning.mlkitscanner.scan.callback.act.MNScanCallback; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; +import no.nordicsemi.android.ble.observer.ConnectionObserver; import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat; import no.nordicsemi.android.support.v18.scanner.ScanCallback; import no.nordicsemi.android.support.v18.scanner.ScanFilter; @@ -80,6 +83,7 @@ public class AddDeviceActivity_copy extends BaseActivity mDeviceList = new ArrayList<>(); private Set discoveredMacSet = new HashSet<>(); + private WaterDeviceManager waterDeviceManager; @Override public DevicePresenter createPresenter() { @@ -189,8 +193,160 @@ public class AddDeviceActivity_copy extends BaseActivity { + Log.e("TEST", "设备响应: " + Arrays.toString(bytes)); + runOnUiThread(() -> { + // TODO: 处理设备返回的数据,比如 WiFi 配置响应 + handleDeviceResponse(bytes); + }); + }); + + // 连接设备 + waterDeviceManager.connect(device) + .retry(3, 100) // 重试3次,间隔100ms + .done(bluetoothDevice -> { + Log.e("TEST", "连接成功: " + deviceName); + runOnUiThread(() -> { + ToastUtil.showShort(mContext, "连接成功: " + deviceName); + // TODO: 连接成功后,发送 WiFi 配置 + // sendWifiConfig("SSID", "PASSWORD"); + }); + }) + .fail((bluetoothDevice, status) -> { + Log.e("TEST", "连接失败: " + status); + runOnUiThread(() -> { + ToastUtil.showShort(mContext, "连接失败,请重试"); + }); + }) + .enqueue(); + + waterDeviceManager.setConnectionObserver(new ConnectionObserver() { + + @Override + public void onDeviceConnecting(@NonNull BluetoothDevice device) { + Log.e("TEST", "onDeviceConnecting"); + } + + @Override + public void onDeviceConnected(@NonNull BluetoothDevice device) { + Log.e("TEST", "onDeviceConnected"); + } + + @Override + public void onDeviceFailedToConnect(@NonNull BluetoothDevice device, int reason) { + Log.e("TEST", "onDeviceFailedToConnect"); + } + + @Override + public void onDeviceReady(@NonNull BluetoothDevice device) { + Log.e("TEST", "onDeviceReady"); + } + + @Override + public void onDeviceDisconnecting(@NonNull BluetoothDevice device) { + Log.e("TEST", "onDeviceDisconnecting"); + } + + @Override + public void onDeviceDisconnected( + @NonNull BluetoothDevice device, + int reason) { + + Log.e("TEST", "onDeviceDisconnected reason=" + reason); + } + }); + } + + /** + * 发送 WiFi 配置到设备 + */ + public void sendWifiConfig(String ssid, String password) { + if (waterDeviceManager == null || !waterDeviceManager.isBlConnected()) { + Log.e("TEST", "设备未连接,无法发送WiFi配置"); + return; + } + + // TODO: 根据设备协议组装数据 + // 示例:假设协议是 [header(1) + ssid_len(1) + ssid(n) + pwd_len(1) + pwd(m)] + byte[] ssidBytes = ssid.getBytes(); + byte[] pwdBytes = password.getBytes(); + + byte[] data = new byte[2 + ssidBytes.length + 2 + pwdBytes.length]; + int index = 0; + data[index++] = 0x01; // header + data[index++] = (byte) ssidBytes.length; + System.arraycopy(ssidBytes, 0, data, index, ssidBytes.length); + index += ssidBytes.length; + data[index++] = (byte) pwdBytes.length; + System.arraycopy(pwdBytes, 0, data, index, pwdBytes.length); + + waterDeviceManager.send(data); + Log.e("TEST", "发送WiFi配置: SSID=" + ssid + ", PWD=" + password); + } + + /** + * 处理设备响应数据 + */ + private void handleDeviceResponse(byte[] data) { + if (data == null || data.length == 0) { + return; + } + + // TODO: 根据设备协议解析响应数据 + // 示例:假设响应格式是 [type(1) + status(1) + ...] + Log.e("TEST", "处理设备响应: " + Arrays.toString(data)); + + if (data.length >= 2) { + byte type = data[0]; + byte status = data[1]; + + switch (type) { + case 0x01: // WiFi配置响应 + if (status == 0x00) { + ToastUtil.showShort(mContext, "WiFi配置成功"); + // TODO: 下一步操作 + } else { + ToastUtil.showShort(mContext, "WiFi配置失败,错误码: " + status); + } + break; + default: + Log.e("TEST", "未知响应类型: " + type); + break; + } + } } /** @@ -260,9 +416,18 @@ public class AddDeviceActivity_copy extends BaseActivity { - byte[] bytes = data.getValue(); + Log.e("TEST", "收到数据: " + Arrays.toString(bytes)); - Log.e("TEST", "收到数据: " - + Arrays.toString(bytes)); + if (dataListener != null) { + dataListener.onDataReceived(bytes); + } }); enableNotifications(notifyCharacteristic) .enqueue(); } + // @Override +// public boolean isRequiredServiceSupported(@NonNull BluetoothGatt gatt) { +// +// BluetoothGattService service = +// gatt.getService(UUID.fromString( +// AppConfig.BLUETOOTH_DEVICE_UUID)); +// +// if (service == null) { +// return false; +// } +// +// writeCharacteristic = +// service.getCharacteristic(UUID.fromString( +// AppConfig.BLUETOOTH_DEVICE_UUID)); +// +// notifyCharacteristic = +// service.getCharacteristic(UUID.fromString( +// AppConfig.BLUETOOTH_DEVICE_UUID)); +// +// return writeCharacteristic != null +// && notifyCharacteristic != null; +// } @Override - public boolean isRequiredServiceSupported(@NonNull BluetoothGatt gatt) { + public boolean isRequiredServiceSupported( + @NonNull BluetoothGatt gatt) { - BluetoothGattService service = - gatt.getService(UUID.fromString( - "0000ffff-0000-1000-8000-00805f9b34fb")); + for (BluetoothGattService service : + gatt.getServices()) { - if (service == null) { - return false; + Log.e("TEST", + "Service=" + service.getUuid()); + + for (BluetoothGattCharacteristic c : + service.getCharacteristics()) { + + int properties = c.getProperties(); + + Log.e("TEST", + "Characteristic=" + + c.getUuid() + + " props=" + + properties); + + if ((properties & + BluetoothGattCharacteristic.PROPERTY_WRITE) + != 0) { + + writeCharacteristic = c; + } + + if ((properties & + BluetoothGattCharacteristic.PROPERTY_NOTIFY) + != 0) { + + notifyCharacteristic = c; + } + } } - writeCharacteristic = - service.getCharacteristic(UUID.fromString( - "0000ff01-0000-1000-8000-00805f9b34fb")); + Log.e("TEST", + "write=" + + (writeCharacteristic != null + ? writeCharacteristic.getUuid() + : "null")); - notifyCharacteristic = - service.getCharacteristic(UUID.fromString( - "0000ff02-0000-1000-8000-00805f9b34fb")); + Log.e("TEST", + "notify=" + + (notifyCharacteristic != null + ? notifyCharacteristic.getUuid() + : "null")); return writeCharacteristic != null && notifyCharacteristic != null; @@ -83,10 +147,23 @@ public class WaterDeviceManager extends BleManager { public void send(byte[] data) { if (writeCharacteristic == null) { + Log.e("TEST", "send: Write characteristic is null"); return; } writeCharacteristic(writeCharacteristic, data) .enqueue(); } + + public boolean isBlConnected() { + // 通过反射或状态检查来判断是否已连接 + // BleManager 没有直接的 isConnected 方法,需要检查内部状态 + try { + // 检查 writeCharacteristic 是否可用(连接后会初始化) + return writeCharacteristic != null; + } catch (Exception e) { + return false; + } + } + }