mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-10 19:52:24 +00:00
try to fix service, again
This commit is contained in:
@@ -258,220 +258,249 @@ class AirPodsService: Service() {
|
|||||||
HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;")
|
HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;")
|
||||||
val uuid: ParcelUuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
|
val uuid: ParcelUuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a")
|
||||||
|
|
||||||
try {
|
if (isConnected != true) {
|
||||||
socket.close()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
socket = HiddenApiBypass.newInstance(
|
|
||||||
BluetoothSocket::class.java,
|
|
||||||
3,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
device,
|
|
||||||
0x1001,
|
|
||||||
uuid
|
|
||||||
) as BluetoothSocket
|
|
||||||
}
|
|
||||||
catch (
|
|
||||||
e: Exception
|
|
||||||
) {
|
|
||||||
e.printStackTrace()
|
|
||||||
try {
|
try {
|
||||||
socket = HiddenApiBypass.newInstance(
|
socket = HiddenApiBypass.newInstance(
|
||||||
BluetoothSocket::class.java,
|
BluetoothSocket::class.java,
|
||||||
3,
|
3,
|
||||||
1,
|
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
device,
|
device,
|
||||||
0x1001,
|
0x1001,
|
||||||
uuid
|
uuid
|
||||||
) as BluetoothSocket
|
) as BluetoothSocket
|
||||||
}
|
} catch (
|
||||||
catch (
|
|
||||||
e: Exception
|
e: Exception
|
||||||
) {
|
) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
try {
|
||||||
|
socket = HiddenApiBypass.newInstance(
|
||||||
|
BluetoothSocket::class.java,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
device,
|
||||||
|
0x1001,
|
||||||
|
uuid
|
||||||
|
) as BluetoothSocket
|
||||||
|
} catch (
|
||||||
|
e: Exception
|
||||||
|
) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
socket.connect()
|
socket.connect()
|
||||||
this@AirPodsService.device = device
|
this@AirPodsService.device = device
|
||||||
isConnected = true
|
isConnected = true
|
||||||
socket.let { it ->
|
socket.let { it ->
|
||||||
it.outputStream.write(Enums.HANDSHAKE.value)
|
it.outputStream.write(Enums.HANDSHAKE.value)
|
||||||
it.outputStream.flush()
|
it.outputStream.flush()
|
||||||
it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value)
|
it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value)
|
||||||
it.outputStream.flush()
|
it.outputStream.flush()
|
||||||
it.outputStream.write(Enums.REQUEST_NOTIFICATIONS.value)
|
it.outputStream.write(Enums.REQUEST_NOTIFICATIONS.value)
|
||||||
it.outputStream.flush()
|
it.outputStream.flush()
|
||||||
sendBroadcast(
|
sendBroadcast(
|
||||||
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
||||||
.putExtra("device", device)
|
.putExtra("device", device)
|
||||||
)
|
)
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
while (socket.isConnected == true) {
|
while (socket.isConnected == true) {
|
||||||
socket.let {
|
socket.let {
|
||||||
val audioManager = this@AirPodsService.getSystemService(AUDIO_SERVICE) as AudioManager
|
val audioManager =
|
||||||
MediaController.initialize(audioManager)
|
this@AirPodsService.getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
val buffer = ByteArray(1024)
|
MediaController.initialize(audioManager)
|
||||||
val bytesRead = it.inputStream.read(buffer)
|
val buffer = ByteArray(1024)
|
||||||
var data: ByteArray = byteArrayOf()
|
val bytesRead = it.inputStream.read(buffer)
|
||||||
if (bytesRead > 0) {
|
var data: ByteArray = byteArrayOf()
|
||||||
data = buffer.copyOfRange(0, bytesRead)
|
if (bytesRead > 0) {
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DATA).apply {
|
data = buffer.copyOfRange(0, bytesRead)
|
||||||
putExtra("data", buffer.copyOfRange(0, bytesRead))
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DATA).apply {
|
||||||
})
|
putExtra("data", buffer.copyOfRange(0, bytesRead))
|
||||||
val bytes = buffer.copyOfRange(0, bytesRead)
|
})
|
||||||
val formattedHex = bytes.joinToString(" ") { "%02X".format(it) }
|
val bytes = buffer.copyOfRange(0, bytesRead)
|
||||||
Log.d("AirPods Data", "Data received: $formattedHex")
|
val formattedHex = bytes.joinToString(" ") { "%02X".format(it) }
|
||||||
}
|
Log.d("AirPods Data", "Data received: $formattedHex")
|
||||||
else if (bytesRead == -1) {
|
} else if (bytesRead == -1) {
|
||||||
Log.d("AirPods Service", "Socket closed (bytesRead = -1)")
|
Log.d("AirPods Service", "Socket closed (bytesRead = -1)")
|
||||||
// socket.close()
|
// socket.close()
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED))
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED))
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
var inEar = false
|
var inEar = false
|
||||||
var inEarData = listOf<Boolean>()
|
var inEarData = listOf<Boolean>()
|
||||||
if (earDetectionNotification.isEarDetectionData(data)) {
|
if (earDetectionNotification.isEarDetectionData(data)) {
|
||||||
earDetectionNotification.setStatus(data)
|
earDetectionNotification.setStatus(data)
|
||||||
sendBroadcast(Intent(AirPodsNotifications.EAR_DETECTION_DATA).apply {
|
sendBroadcast(Intent(AirPodsNotifications.EAR_DETECTION_DATA).apply {
|
||||||
val list = earDetectionNotification.status
|
val list = earDetectionNotification.status
|
||||||
val bytes = ByteArray(2)
|
val bytes = ByteArray(2)
|
||||||
bytes[0] = list[0]
|
bytes[0] = list[0]
|
||||||
bytes[1] = list[1]
|
bytes[1] = list[1]
|
||||||
putExtra("data", bytes)
|
putExtra("data", bytes)
|
||||||
})
|
})
|
||||||
Log.d("AirPods Parser", "Ear Detection: ${earDetectionNotification.status[0]} ${earDetectionNotification.status[1]}")
|
Log.d(
|
||||||
var justEnabledA2dp = false
|
"AirPods Parser",
|
||||||
earReceiver = object : BroadcastReceiver() {
|
"Ear Detection: ${earDetectionNotification.status[0]} ${earDetectionNotification.status[1]}"
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
)
|
||||||
val data = intent.getByteArrayExtra("data")
|
var justEnabledA2dp = false
|
||||||
if (data != null && earDetectionEnabled) {
|
earReceiver = object : BroadcastReceiver() {
|
||||||
inEar = if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
data[0] == 0x00.toByte() || data[1] == 0x00.toByte()
|
val data = intent.getByteArrayExtra("data")
|
||||||
} else {
|
if (data != null && earDetectionEnabled) {
|
||||||
data[0] == 0x00.toByte() && data[1] == 0x00.toByte()
|
inEar =
|
||||||
}
|
if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) {
|
||||||
|
data[0] == 0x00.toByte() || data[1] == 0x00.toByte()
|
||||||
val newInEarData = listOf(data[0] == 0x00.toByte(), data[1] == 0x00.toByte())
|
} else {
|
||||||
if (newInEarData.contains(true) && inEarData == listOf(false, false)) {
|
data[0] == 0x00.toByte() && data[1] == 0x00.toByte()
|
||||||
connectAudio(this@AirPodsService, device)
|
|
||||||
justEnabledA2dp = true
|
|
||||||
val bluetoothAdapter = this@AirPodsService.getSystemService(BluetoothManager::class.java).adapter
|
|
||||||
bluetoothAdapter.getProfileProxy(
|
|
||||||
this@AirPodsService, object : BluetoothProfile.ServiceListener {
|
|
||||||
override fun onServiceConnected(
|
|
||||||
profile: Int,
|
|
||||||
proxy: BluetoothProfile
|
|
||||||
) {
|
|
||||||
if (profile == BluetoothProfile.A2DP) {
|
|
||||||
val connectedDevices =
|
|
||||||
proxy.connectedDevices
|
|
||||||
if (connectedDevices.isNotEmpty()) {
|
|
||||||
MediaController.sendPlay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bluetoothAdapter.closeProfileProxy(
|
|
||||||
profile,
|
|
||||||
proxy
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceDisconnected(
|
|
||||||
profile: Int
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
,BluetoothProfile.A2DP
|
|
||||||
|
val newInEarData = listOf(
|
||||||
|
data[0] == 0x00.toByte(),
|
||||||
|
data[1] == 0x00.toByte()
|
||||||
)
|
)
|
||||||
|
if (newInEarData.contains(true) && inEarData == listOf(
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
connectAudio(this@AirPodsService, device)
|
||||||
|
justEnabledA2dp = true
|
||||||
|
val bluetoothAdapter =
|
||||||
|
this@AirPodsService.getSystemService(
|
||||||
|
BluetoothManager::class.java
|
||||||
|
).adapter
|
||||||
|
bluetoothAdapter.getProfileProxy(
|
||||||
|
this@AirPodsService,
|
||||||
|
object : BluetoothProfile.ServiceListener {
|
||||||
|
override fun onServiceConnected(
|
||||||
|
profile: Int,
|
||||||
|
proxy: BluetoothProfile
|
||||||
|
) {
|
||||||
|
if (profile == BluetoothProfile.A2DP) {
|
||||||
|
val connectedDevices =
|
||||||
|
proxy.connectedDevices
|
||||||
|
if (connectedDevices.isNotEmpty()) {
|
||||||
|
MediaController.sendPlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bluetoothAdapter.closeProfileProxy(
|
||||||
|
profile,
|
||||||
|
proxy
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
override fun onServiceDisconnected(
|
||||||
else if (newInEarData == listOf(false, false)){
|
profile: Int
|
||||||
disconnectAudio(this@AirPodsService, device)
|
) {
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
BluetoothProfile.A2DP
|
||||||
|
)
|
||||||
|
|
||||||
inEarData = newInEarData
|
} else if (newInEarData == listOf(false, false)) {
|
||||||
|
disconnectAudio(this@AirPodsService, device)
|
||||||
if (inEar == true) {
|
}
|
||||||
if (!justEnabledA2dp) {
|
|
||||||
justEnabledA2dp = false
|
inEarData = newInEarData
|
||||||
MediaController.sendPlay()
|
|
||||||
|
if (inEar == true) {
|
||||||
|
if (!justEnabledA2dp) {
|
||||||
|
justEnabledA2dp = false
|
||||||
|
MediaController.sendPlay()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MediaController.sendPause()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
MediaController.sendPause()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val earIntentFilter = IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA)
|
val earIntentFilter =
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA)
|
||||||
this@AirPodsService.registerReceiver(earReceiver, earIntentFilter,
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
RECEIVER_EXPORTED
|
this@AirPodsService.registerReceiver(
|
||||||
|
earReceiver, earIntentFilter,
|
||||||
|
RECEIVER_EXPORTED
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this@AirPodsService.registerReceiver(
|
||||||
|
earReceiver,
|
||||||
|
earIntentFilter
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (ancNotification.isANCData(data)) {
|
||||||
|
ancNotification.setStatus(data)
|
||||||
|
sendBroadcast(Intent(AirPodsNotifications.ANC_DATA).apply {
|
||||||
|
putExtra("data", ancNotification.status)
|
||||||
|
})
|
||||||
|
Log.d("AirPods Parser", "ANC: ${ancNotification.status}")
|
||||||
|
} else if (batteryNotification.isBatteryData(data)) {
|
||||||
|
batteryNotification.setBattery(data)
|
||||||
|
sendBroadcast(Intent(AirPodsNotifications.BATTERY_DATA).apply {
|
||||||
|
putParcelableArrayListExtra(
|
||||||
|
"data",
|
||||||
|
ArrayList(batteryNotification.getBattery())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
updateNotificationContent(
|
||||||
|
true,
|
||||||
|
this@AirPodsService.getSharedPreferences(
|
||||||
|
"settings",
|
||||||
|
MODE_PRIVATE
|
||||||
|
).getString("name", device.name),
|
||||||
|
batteryNotification.getBattery()
|
||||||
|
)
|
||||||
|
for (battery in batteryNotification.getBattery()) {
|
||||||
|
Log.d(
|
||||||
|
"AirPods Parser",
|
||||||
|
"${battery.getComponentName()}: ${battery.getStatusName()} at ${battery.level}% "
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (batteryNotification.getBattery()[0].status == 1 && batteryNotification.getBattery()[1].status == 1) {
|
||||||
|
disconnectAudio(this@AirPodsService, device)
|
||||||
|
} else {
|
||||||
|
connectAudio(this@AirPodsService, device)
|
||||||
|
}
|
||||||
|
} else if (conversationAwarenessNotification.isConversationalAwarenessData(
|
||||||
|
data
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
conversationAwarenessNotification.setData(data)
|
||||||
|
sendBroadcast(Intent(AirPodsNotifications.CA_DATA).apply {
|
||||||
|
putExtra("data", conversationAwarenessNotification.status)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if (conversationAwarenessNotification.status == 1.toByte() || conversationAwarenessNotification.status == 2.toByte()) {
|
||||||
|
MediaController.startSpeaking()
|
||||||
|
} else if (conversationAwarenessNotification.status == 8.toByte() || conversationAwarenessNotification.status == 9.toByte()) {
|
||||||
|
MediaController.stopSpeaking()
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(
|
||||||
|
"AirPods Parser",
|
||||||
|
"Conversation Awareness: ${conversationAwarenessNotification.status}"
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
this@AirPodsService.registerReceiver(earReceiver, earIntentFilter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ancNotification.isANCData(data)) {
|
|
||||||
ancNotification.setStatus(data)
|
|
||||||
sendBroadcast(Intent(AirPodsNotifications.ANC_DATA).apply {
|
|
||||||
putExtra("data", ancNotification.status)
|
|
||||||
})
|
|
||||||
Log.d("AirPods Parser", "ANC: ${ancNotification.status}")
|
|
||||||
}
|
|
||||||
else if (batteryNotification.isBatteryData(data)) {
|
|
||||||
batteryNotification.setBattery(data)
|
|
||||||
sendBroadcast(Intent(AirPodsNotifications.BATTERY_DATA).apply {
|
|
||||||
putParcelableArrayListExtra("data", ArrayList(batteryNotification.getBattery()))
|
|
||||||
})
|
|
||||||
updateNotificationContent(true, this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE).getString("name", device.name), batteryNotification.getBattery())
|
|
||||||
for (battery in batteryNotification.getBattery()) {
|
|
||||||
Log.d("AirPods Parser", "${battery.getComponentName()}: ${battery.getStatusName()} at ${battery.level}% ")
|
|
||||||
}
|
|
||||||
if (batteryNotification.getBattery()[0].status == 1 && batteryNotification.getBattery()[1].status == 1) {
|
|
||||||
disconnectAudio(this@AirPodsService, device)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
connectAudio(this@AirPodsService, device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (conversationAwarenessNotification.isConversationalAwarenessData(data)) {
|
|
||||||
conversationAwarenessNotification.setData(data)
|
|
||||||
sendBroadcast(Intent(AirPodsNotifications.CA_DATA).apply {
|
|
||||||
putExtra("data", conversationAwarenessNotification.status)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
if (conversationAwarenessNotification.status == 1.toByte() || conversationAwarenessNotification.status == 2.toByte()) {
|
|
||||||
MediaController.startSpeaking()
|
|
||||||
} else if (conversationAwarenessNotification.status == 8.toByte() || conversationAwarenessNotification.status == 9.toByte()) {
|
|
||||||
MediaController.stopSpeaking()
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("AirPods Parser", "Conversation Awareness: ${conversationAwarenessNotification.status}")
|
|
||||||
}
|
|
||||||
else { }
|
|
||||||
}
|
}
|
||||||
|
Log.d("AirPods Service", "Socket closed")
|
||||||
|
isConnected = false
|
||||||
|
socket.close()
|
||||||
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED))
|
||||||
}
|
}
|
||||||
Log.d("AirPods Service", "Socket closed")
|
|
||||||
isConnected = false
|
|
||||||
socket.close()
|
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED))
|
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Log.d("AirPodsService", "Failed to connect to socket")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
Log.d("AirPodsService", "Failed to connect to socket")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
|
|||||||
),
|
),
|
||||||
topBar = {
|
topBar = {
|
||||||
val darkMode = MaterialTheme.colorScheme.surface.luminance() < 0.5
|
val darkMode = MaterialTheme.colorScheme.surface.luminance() < 0.5
|
||||||
val mdensity = remember { mutableFloatStateOf(1f) }
|
val mDensity = remember { mutableFloatStateOf(1f) }
|
||||||
CenterAlignedTopAppBar(
|
CenterAlignedTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
@@ -530,14 +530,14 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.hazeChild(
|
.hazeChild(
|
||||||
state = hazeState,
|
state = hazeState,
|
||||||
style = CupertinoMaterials.thin(),
|
style = CupertinoMaterials.regular(),
|
||||||
block = {
|
block = {
|
||||||
// make the background transparent when not scrolled yet
|
// make the background transparent when not scrolled yet
|
||||||
alpha = if (verticalScrollState.value > 55.dp.value * mdensity.floatValue) 1f else 0f
|
alpha = if (verticalScrollState.value > 55.dp.value * mDensity.floatValue) 1f else 0f
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
mdensity.value = density
|
mDensity.floatValue = density
|
||||||
val strokeWidth = 0.7.dp.value * density
|
val strokeWidth = 0.7.dp.value * density
|
||||||
val y = size.height - strokeWidth / 2
|
val y = size.height - strokeWidth / 2
|
||||||
if (verticalScrollState.value > 55.dp.value * density) {
|
if (verticalScrollState.value > 55.dp.value * density) {
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
|||||||
@Composable
|
@Composable
|
||||||
fun DebugScreen(navController: NavController) {
|
fun DebugScreen(navController: NavController) {
|
||||||
val hazeState = remember { HazeState() }
|
val hazeState = remember { HazeState() }
|
||||||
|
val text = remember { mutableStateListOf<String>("Log Start") }
|
||||||
|
val context = LocalContext.current
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
@@ -82,7 +86,14 @@ fun DebugScreen(navController: NavController) {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.hazeChild(
|
.hazeChild(
|
||||||
state = hazeState,
|
state = hazeState,
|
||||||
style = CupertinoMaterials.thin()
|
style = CupertinoMaterials.thin(),
|
||||||
|
block = {
|
||||||
|
alpha = if (listState.firstVisibleItemIndex > 0) {
|
||||||
|
1f
|
||||||
|
} else {
|
||||||
|
0f
|
||||||
|
}
|
||||||
|
}
|
||||||
),
|
),
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
containerColor = Color.Transparent
|
containerColor = Color.Transparent
|
||||||
@@ -92,16 +103,11 @@ fun DebugScreen(navController: NavController) {
|
|||||||
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000)
|
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000)
|
||||||
else Color(0xFFF2F2F7),
|
else Color(0xFFF2F2F7),
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
|
||||||
val text = remember { mutableStateListOf<String>("Log Start") }
|
|
||||||
val context = LocalContext.current
|
|
||||||
val listState = rememberLazyListState()
|
|
||||||
|
|
||||||
val receiver = object : BroadcastReceiver() {
|
val receiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val data = intent.getByteArrayExtra("data")
|
val data = intent.getByteArrayExtra("data")
|
||||||
data?.let {
|
data?.let {
|
||||||
text.add(">" + it.joinToString(" ") { byte -> "%02X".format(byte) }) // Use ">" for received packets
|
text.add(">" + it.joinToString(" ") { byte -> "%02X".format(byte) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,12 +127,10 @@ fun DebugScreen(navController: NavController) {
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
// .padding(paddingValues)
|
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.haze(hazeState)
|
.haze(hazeState)
|
||||||
.padding(top = 0.dp)
|
.padding(top = 0.dp)
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(55.dp))
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -136,7 +140,12 @@ fun DebugScreen(navController: NavController) {
|
|||||||
items(text.size) { index ->
|
items(text.size) { index ->
|
||||||
val message = text[index]
|
val message = text[index]
|
||||||
val isSent = message.startsWith(">")
|
val isSent = message.startsWith(">")
|
||||||
val backgroundColor = if (isSent) Color(0xFFE1FFC7) else Color(0xFFD1D1D1)
|
val backgroundColor =
|
||||||
|
if (isSent) Color(0xFFE1FFC7) else Color(0xFFD1D1D1)
|
||||||
|
|
||||||
|
if (message == "Log Start") {
|
||||||
|
Spacer(modifier = Modifier.height(115.dp))
|
||||||
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -155,11 +164,13 @@ fun DebugScreen(navController: NavController) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = if (isSent) message.substring(1) else message, // Remove the ">" from sent packets
|
text = if (isSent) message.substring(1) else message,
|
||||||
fontFamily = FontFamily(Font(R.font.hack)),
|
fontFamily = FontFamily(Font(R.font.hack)),
|
||||||
color = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000)
|
color = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(
|
||||||
|
0xFF000000
|
||||||
|
)
|
||||||
else Color(0xFF000000),
|
else Color(0xFF000000),
|
||||||
modifier = Modifier.weight(1f) // Allows text to take available space
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isSent) {
|
if (isSent) {
|
||||||
@@ -170,6 +181,7 @@ fun DebugScreen(navController: NavController) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
val airPodsService = remember { mutableStateOf<AirPodsService?>(null) }
|
val airPodsService = remember { mutableStateOf<AirPodsService?>(null) }
|
||||||
|
|
||||||
val serviceConnection = object : ServiceConnection {
|
val serviceConnection = object : ServiceConnection {
|
||||||
@@ -200,13 +212,14 @@ fun DebugScreen(navController: NavController) {
|
|||||||
label = { Text("Packet") },
|
label = { Text("Packet") },
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp), // Padding for the input field
|
.padding(horizontal = 8.dp)
|
||||||
|
.padding(bottom = 5.dp),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
airPodsService.value?.sendPacket(packet.value.text)
|
airPodsService.value?.sendPacket(packet.value.text)
|
||||||
text.add(packet.value.text) // Add sent message directly without prefix
|
text.add(packet.value.text)
|
||||||
packet.value = TextFieldValue("") // Clear input field after sending
|
packet.value = TextFieldValue("")
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
|
|||||||
Reference in New Issue
Block a user