ble: 다중 기기 페어링 영속화 (KnownDeviceStore)
기존 단일 last_device_address/name 키를 JSON 리스트로 확장. 여러 각도 변형 기기를 등록해두고 PIN 재입력 없이 골라 연결 가능. KnownDeviceStore (services/): - getAll / add / remove / mostRecent - 구 단일 키 자동 마이그레이션 (read 시 흡수, 새 add 시 호환 유지) BleManager: - 연결 성공 시 KnownDeviceStore.add 호출 (단일 키 직접 쓰기 제거) - autoConnectLastDevice: mostRecent() 사용 - disconnectAndUnbond: known list 에서도 제거 - connectByAddress(addr,name) 신규 — 스캔 결과 없어도 OS bond 가 있으면 바로 연결. KnownDeviceStore 에서 골라 호출. - unbondAndRemoveAddress(addr) 신규 — 연결 안 된 기기도 페어링 해제 가능 (removeBond + KnownDeviceStore.remove)
This commit is contained in:
@@ -246,14 +246,58 @@ class BleManager private constructor(private val context: Context) {
|
||||
handler.postDelayed(timeout, 10000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 주소의 known device 페어링 해제 — 현재 연결된 기기가 아니어도 사용 가능.
|
||||
* 연결된 상태라면 일반 disconnectAndUnbond() 를 사용.
|
||||
*/
|
||||
fun unbondAndRemoveAddress(address: String) {
|
||||
// 현재 연결된 기기를 해제하려는 경우
|
||||
if (bluetoothGatt?.device?.address == address) {
|
||||
disconnectAndUnbond()
|
||||
return
|
||||
}
|
||||
// 연결 안 된 known device — OS bond 만 끊고 list 에서 제거
|
||||
val adapter = bluetoothAdapter ?: return
|
||||
val device = runCatching { adapter.getRemoteDevice(address) }.getOrNull()
|
||||
device?.let { dev ->
|
||||
try {
|
||||
val method = dev.javaClass.getMethod("removeBond")
|
||||
method.invoke(dev)
|
||||
logd { "removeBond called for ${dev.address}" }
|
||||
} catch (e: Exception) {
|
||||
logw { "removeBond failed: ${e.message}" }
|
||||
}
|
||||
}
|
||||
com.example.medilightv2android.services.KnownDeviceStore.remove(context, address)
|
||||
debugLogger.info("DEVICE_UNREGISTERED $address")
|
||||
}
|
||||
|
||||
/**
|
||||
* 저장된 기기 주소로 직접 연결. 스캔 결과에 안 잡혀도 OS bond 가 있으면 바로 됨.
|
||||
* KnownDeviceStore 에서 골라 호출.
|
||||
*/
|
||||
fun connectByAddress(address: String, name: String) {
|
||||
val adapter = bluetoothAdapter ?: run {
|
||||
connectionError.value = "Bluetooth not available"
|
||||
return
|
||||
}
|
||||
val device = try {
|
||||
adapter.getRemoteDevice(address)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
connectionError.value = "Invalid device address"
|
||||
return
|
||||
}
|
||||
connect(BleDevice(device = device, rssi = 0))
|
||||
// discoveredDevices 에 없을 수 있으므로 name 을 별도로 저장 (기존 connect 가 onConnected 시점에 name 설정)
|
||||
connectedDeviceName.value = name
|
||||
}
|
||||
|
||||
/** 저장된 마지막 기기에 자동 연결 시도 */
|
||||
fun autoConnectLastDevice() {
|
||||
if (isConnected.value) return
|
||||
val prefs = context.getSharedPreferences("medilight_prefs", Context.MODE_PRIVATE)
|
||||
val address = prefs.getString("last_device_address", null) ?: return
|
||||
val name = prefs.getString("last_device_name", null) ?: return
|
||||
debugLogger.info("AUTO_CONNECT attempting $name ($address)")
|
||||
lastConnectedAddress = address
|
||||
val recent = com.example.medilightv2android.services.KnownDeviceStore.mostRecent(context) ?: return
|
||||
debugLogger.info("AUTO_CONNECT attempting ${recent.name} (${recent.address})")
|
||||
lastConnectedAddress = recent.address
|
||||
scheduleAutoReconnect()
|
||||
}
|
||||
|
||||
@@ -308,10 +352,11 @@ class BleManager private constructor(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// 저장된 기기 정보 삭제
|
||||
// 저장된 기기 정보 삭제 — known device list 에서도 제거
|
||||
try {
|
||||
val prefs = context.getSharedPreferences("medilight_prefs", Context.MODE_PRIVATE)
|
||||
prefs.edit().remove("last_device_address").remove("last_device_name").apply()
|
||||
device?.let { dev ->
|
||||
com.example.medilightv2android.services.KnownDeviceStore.remove(context, dev.address)
|
||||
}
|
||||
} catch (_: Exception) {}
|
||||
|
||||
debugLogger.info("DEVICE_UNREGISTERED")
|
||||
@@ -809,11 +854,9 @@ class BleManager private constructor(private val context: Context) {
|
||||
debugLogger.connected(connectedDeviceName.value, gatt.device.address)
|
||||
|
||||
try {
|
||||
val prefs = context.getSharedPreferences("medilight_prefs", Context.MODE_PRIVATE)
|
||||
prefs.edit()
|
||||
.putString("last_device_address", gatt.device.address)
|
||||
.putString("last_device_name", connectedDeviceName.value)
|
||||
.apply()
|
||||
com.example.medilightv2android.services.KnownDeviceStore.add(
|
||||
context, gatt.device.address, connectedDeviceName.value
|
||||
)
|
||||
} catch (_: Exception) {}
|
||||
|
||||
// MTU 247 요청 (reb: 208B 패킷 드롭 방지)
|
||||
|
||||
Reference in New Issue
Block a user