From 34ace1fc6efa278f25a8bf6324e7d4c00b974169 Mon Sep 17 00:00:00 2001 From: Kavish Devar Date: Mon, 16 Dec 2024 16:13:52 +0530 Subject: [PATCH] try adding widget; add previews to each composable --- android/app/src/main/AndroidManifest.xml | 2 +- .../java/me/kavishdevar/aln/BatteryWidget.kt | 42 +- .../java/me/kavishdevar/aln/MainActivity.kt | 2 + .../me/kavishdevar/aln/OldAirPodsService.kt | 463 ------------------ .../aln/composables/AccessibilitySettings.kt | 2 +- .../aln/composables/AdaptiveStrengthSlider.kt | 2 +- .../aln/composables/AudioSettings.kt | 2 +- .../aln/composables/BatteryView.kt | 10 +- .../ConversationalAwarenessSwitch.kt | 2 +- .../aln/composables/IndependentToggle.kt | 2 +- .../composables/LoudSoundReductionSwitch.kt | 2 +- .../aln/composables/NoiseControlButton.kt | 2 +- .../aln/composables/NoiseControlSettings.kt | 6 +- .../composables/PersonalizedVolumeSwitch.kt | 2 +- .../aln/composables/SinglePodANCSwitch.kt | 2 +- .../aln/composables/ToneVolumeSlider.kt | 2 +- .../aln/composables/VolumeControlSwitch.kt | 2 +- .../kavishdevar/aln/receivers/BootReceiver.kt | 2 +- .../aln/screens/AirPodsSettingsScreen.kt | 71 ++- .../me/kavishdevar/aln/screens/DebugScreen.kt | 4 +- .../aln/screens/PressAndHoldSettingsScreen.kt | 2 +- .../aln/services/AirPodsQSService.kt | 5 +- .../aln/{ => services}/AirPodsService.kt | 54 +- .../me/kavishdevar/aln/{ => utils}/Packets.kt | 2 +- .../me/kavishdevar/aln/{ => utils}/Window.kt | 4 +- .../app_widget_inner_view_background.xml | 1 - .../main/res/layout-v31/battery_widget.xml | 72 +++ .../src/main/res/layout/battery_widget.xml | 79 ++- .../app/src/main/res/values-night/colors.xml | 2 + android/app/src/main/res/values/colors.xml | 6 +- android/app/src/main/res/values/strings.xml | 4 +- android/app/src/main/res/values/themes.xml | 4 +- .../main/res/xml-v31/battery_widget_info.xml | 14 + 33 files changed, 302 insertions(+), 571 deletions(-) delete mode 100644 android/app/src/main/java/me/kavishdevar/aln/OldAirPodsService.kt rename android/app/src/main/java/me/kavishdevar/aln/{ => services}/AirPodsService.kt (96%) rename android/app/src/main/java/me/kavishdevar/aln/{ => utils}/Packets.kt (99%) rename android/app/src/main/java/me/kavishdevar/aln/{ => utils}/Window.kt (99%) create mode 100644 android/app/src/main/res/layout-v31/battery_widget.xml create mode 100644 android/app/src/main/res/xml-v31/battery_widget_info.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 83ebc1b..9060d1a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -61,7 +61,7 @@ { -// socket?.outputStream?.write(Enums.NOISE_CANCELLATION_OFF.value) -// } -// 2 -> { -// socket?.outputStream?.write(Enums.NOISE_CANCELLATION_ON.value) -// } -// 3 -> { -// socket?.outputStream?.write(Enums.NOISE_CANCELLATION_TRANSPARENCY.value) -// } -// 4 -> { -// socket?.outputStream?.write(Enums.NOISE_CANCELLATION_ADAPTIVE.value) -// } -// } -// socket?.outputStream?.flush() -// } -// -// fun setCAEnabled(enabled: Boolean) { -// socket?.outputStream?.write(if (enabled) Enums.SET_CONVERSATION_AWARENESS_ON.value else Enums.SET_CONVERSATION_AWARENESS_OFF.value) -// } -// -// fun setOffListeningMode(enabled: Boolean) { -// socket?.outputStream?.write(byteArrayOf(0x04, 0x00 ,0x04, 0x00, 0x09, 0x00, 0x34, if (enabled) 0x01 else 0x02, 0x00, 0x00, 0x00)) -// } -// -// fun setAdaptiveStrength(strength: Int) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x2E, strength.toByte(), 0x00, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setPressSpeed(speed: Int) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x17, speed.toByte(), 0x00, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setPressAndHoldDuration(speed: Int) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x18, speed.toByte(), 0x00, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setNoiseCancellationWithOnePod(enabled: Boolean) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x1B, if (enabled) 0x01 else 0x02, 0x00, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setVolumeControl(enabled: Boolean) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x25, if (enabled) 0x01 else 0x02, 0x00, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setVolumeSwipeSpeed(speed: Int) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x23, speed.toByte(), 0x00, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setToneVolume(volume: Int) { -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x1F, volume.toByte(), 0x50, 0x00, 0x00) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// val earDetectionNotification = AirPodsNotifications.EarDetection() -// val ancNotification = AirPodsNotifications.ANC() -// val batteryNotification = AirPodsNotifications.BatteryNotification() -// val conversationAwarenessNotification = AirPodsNotifications.ConversationalAwarenessNotification() -// -// var earDetectionEnabled = true -// -// fun setCaseChargingSounds(enabled: Boolean) { -// val bytes = byteArrayOf(0x12, 0x3a, 0x00, 0x01, 0x00, 0x08, if (enabled) 0x00 else 0x01) -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// } -// -// fun setEarDetection(enabled: Boolean) { -// earDetectionEnabled = enabled -// } -// -// fun getBattery(): List { -// return batteryNotification.getBattery() -// } -// -// fun getANC(): Int { -// return ancNotification.status -// } -// -// private fun createNotification(): Notification { -// val channelId = "battery" -// val notificationBuilder = NotificationCompat.Builder(this, channelId) -// .setSmallIcon(R.drawable.pro_2_buds) -// .setContentTitle("AirPods Connected") -// .setOngoing(true) -// .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) -// -// val channel = -// NotificationChannel(channelId, "Battery Notification", NotificationManager.IMPORTANCE_LOW) -// -// val notificationManager = getSystemService(NotificationManager::class.java) -// notificationManager.createNotificationChannel(channel) -// return notificationBuilder.build() -// } -// -// fun disconnectAudio(context: Context, device: BluetoothDevice?) { -// val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter -// -// bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener { -// override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { -// if (profile == BluetoothProfile.A2DP) { -// try { -// val method = proxy.javaClass.getMethod("disconnect", BluetoothDevice::class.java) -// method.invoke(proxy, device) -// } catch (e: Exception) { -// e.printStackTrace() -// } finally { -// bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, proxy) -// } -// } -// } -// -// override fun onServiceDisconnected(profile: Int) { } -// }, BluetoothProfile.A2DP) -// -// bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener { -// override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { -// if (profile == BluetoothProfile.HEADSET) { -// try { -// val method = proxy.javaClass.getMethod("disconnect", BluetoothDevice::class.java) -// method.invoke(proxy, device) -// } catch (e: Exception) { -// e.printStackTrace() -// } finally { -// bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) -// } -// } -// } -// -// override fun onServiceDisconnected(profile: Int) { } -// }, BluetoothProfile.HEADSET) -// } -// -// fun connectAudio(context: Context, device: BluetoothDevice?) { -// val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter -// -// bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener { -// override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { -// if (profile == BluetoothProfile.A2DP) { -// try { -// val method = proxy.javaClass.getMethod("connect", BluetoothDevice::class.java) -// method.invoke(proxy, device) -// } catch (e: Exception) { -// e.printStackTrace() -// } finally { -// bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, proxy) -// } -// } -// } -// -// override fun onServiceDisconnected(profile: Int) { } -// }, BluetoothProfile.A2DP) -// -// bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener { -// override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { -// if (profile == BluetoothProfile.HEADSET) { -// try { -// val method = proxy.javaClass.getMethod("connect", BluetoothDevice::class.java) -// method.invoke(proxy, device) -// } catch (e: Exception) { -// e.printStackTrace() -// } finally { -// bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) -// } -// } -// } -// -// override fun onServiceDisconnected(profile: Int) { } -// }, BluetoothProfile.HEADSET) -// } -// -// fun setName(name: String) { -// val nameBytes = name.toByteArray() -// val bytes = byteArrayOf(0x04, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x01, -// nameBytes.size.toByte(), 0x00) + nameBytes -// socket?.outputStream?.write(bytes) -// socket?.outputStream?.flush() -// val hex = bytes.joinToString(" ") { "%02X".format(it) } -// Log.d("OldAirPodsService", "setName: $name, sent packet: $hex") -// } -// -// @SuppressLint("MissingPermission", "InlinedApi") -// override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { -// -// val notification = createNotification() -// startForeground(1, notification) -// -// ServiceManager.setService(this) -// -// if (isConnected) { -// return START_STICKY -// } -// isConnected = true -// -// @Suppress("DEPRECATION") val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) intent?.getParcelableExtra("device", BluetoothDevice::class.java) else intent?.getParcelableExtra("device") -// -// HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;") -// val uuid: ParcelUuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a") -// -// socket = HiddenApiBypass.newInstance(BluetoothSocket::class.java, 3, true, true, device, 0x1001, uuid) as BluetoothSocket? -// try { -// socket?.connect() -// socket?.let { it -> -// it.outputStream.write(Enums.HANDSHAKE.value) -// it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value) -// it.outputStream.write(Enums.REQUEST_NOTIFICATIONS.value) -// sendBroadcast(Intent(AirPodsNotifications.AIRPODS_CONNECTED)) -// it.outputStream.flush() -// -// CoroutineScope(Dispatchers.IO).launch { -// while (socket?.isConnected == true) { -// socket?.let { -// val audioManager = this@OldAirPodsService.getSystemService(AUDIO_SERVICE) as AudioManager -// MediaController.initialize(audioManager) -// val buffer = ByteArray(1024) -// val bytesRead = it.inputStream.read(buffer) -// var data: ByteArray = byteArrayOf() -// if (bytesRead > 0) { -// 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) } -// Log.d("AirPods Data", "Data received: $formattedHex") -// } -// else if (bytesRead == -1) { -// Log.d("AirPods Service", "Socket closed (bytesRead = -1)") -// this@OldAirPodsService.stopForeground(STOP_FOREGROUND_REMOVE) -// socket?.close() -// sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) -// return@launch -// } -// var inEar = false -// var inEarData = listOf() -// if (earDetectionNotification.isEarDetectionData(data)) { -// earDetectionNotification.setStatus(data) -// sendBroadcast(Intent(AirPodsNotifications.EAR_DETECTION_DATA).apply { -// val list = earDetectionNotification.status -// val bytes = ByteArray(2) -// bytes[0] = list[0] -// bytes[1] = list[1] -// putExtra("data", bytes) -// }) -// Log.d("AirPods Parser", "Ear Detection: ${earDetectionNotification.status[0]} ${earDetectionNotification.status[1]}") -// var justEnabledA2dp = false -// val earReceiver = object : BroadcastReceiver() { -// override fun onReceive(context: Context, intent: Intent) { -// val data = intent.getByteArrayExtra("data") -// if (data != null && earDetectionEnabled) { -// inEar = if (data.find { it == 0x02.toByte() } != null || data.find { it == 0x03.toByte() } != null) { -// data[0] == 0x00.toByte() || data[1] == 0x00.toByte() -// } else { -// data[0] == 0x00.toByte() && data[1] == 0x00.toByte() -// } -// -// val newInEarData = listOf(data[0] == 0x00.toByte(), data[1] == 0x00.toByte()) -// if (newInEarData.contains(true) && inEarData == listOf(false, false)) { -// connectAudio(this@OldAirPodsService, device) -// justEnabledA2dp = true -// val bluetoothAdapter = this@OldAirPodsService.getSystemService(BluetoothManager::class.java).adapter -// bluetoothAdapter.getProfileProxy( -// this@OldAirPodsService, 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 -// ) -// -// } -// else if (newInEarData == listOf(false, false)){ -// disconnectAudio(this@OldAirPodsService, device) -// } -// -// inEarData = newInEarData -// -// if (inEar == true) { -// if (!justEnabledA2dp) { -// justEnabledA2dp = false -// MediaController.sendPlay() -// } -// } else { -// MediaController.sendPause() -// } -// } -// } -// } -// -// val earIntentFilter = IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA) -// this@OldAirPodsService.registerReceiver(earReceiver, earIntentFilter, -// RECEIVER_EXPORTED -// ) -// } -// 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())) -// }) -// for (battery in batteryNotification.getBattery()) { -// Log.d("AirPods Parser", "${battery.getComponentName()}: ${battery.getStatusName()} at ${battery.level}% ") -// } -//// if both are charging, disconnect audio profiles -// if (batteryNotification.getBattery()[0].status == 1 && batteryNotification.getBattery()[1].status == 1) { -// disconnectAudio(this@OldAirPodsService, device) -// } -// else { -// connectAudio(this@OldAirPodsService, device) -// } -//// updatePodsStatus(device!!, batteryNotification.getBattery()) -// } -// 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 -// this@OldAirPodsService.stopForeground(STOP_FOREGROUND_REMOVE) -// socket?.close() -// sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) -// } -// } -// } -// catch (e: Exception) { -// Log.e("AirPodsSettingsScreen", "Error connecting to device: ${e.message}") -// } -// return START_STICKY -// } -// -// override fun onDestroy() { -// super.onDestroy() -// socket?.close() -// isConnected = false -// ServiceManager.setService(null) -// } -// -// fun setPVEnabled(enabled: Boolean) { -// var hex = "04 00 04 00 09 00 26 ${if (enabled) "01" else "02"} 00 00 00" -// var bytes = hex.split(" ").map { it.toInt(16).toByte() }.toByteArray() -// socket?.outputStream?.write(bytes) -// hex = "04 00 04 00 17 00 00 00 10 00 12 00 08 E${if (enabled) "6" else "5"} 05 10 02 42 0B 08 50 10 02 1A 05 02 ${if (enabled) "32" else "00"} 00 00 00" -// bytes = hex.split(" ").map { it.toInt(16).toByte() }.toByteArray() -// socket?.outputStream?.write(bytes) -// } -// -// fun setLoudSoundReduction(enabled: Boolean) { -// val hex = "52 1B 00 0${if (enabled) "1" else "0"}" -// val bytes = hex.split(" ").map { it.toInt(16).toByte() }.toByteArray() -// socket?.outputStream?.write(bytes) -// } -//} \ No newline at end of file diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/AccessibilitySettings.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/AccessibilitySettings.kt index eaae5ce..62deaa9 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/AccessibilitySettings.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/AccessibilitySettings.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun AccessibilitySettings(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/AdaptiveStrengthSlider.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/AdaptiveStrengthSlider.kt index 7552f23..89ad389 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/AdaptiveStrengthSlider.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/AdaptiveStrengthSlider.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService import kotlin.math.roundToInt @OptIn(ExperimentalMaterial3Api::class) diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/AudioSettings.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/AudioSettings.kt index a8c06df..9cf772c 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/AudioSettings.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/AudioSettings.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun AudioSettings(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/BatteryView.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/BatteryView.kt index 056b5a7..05be0f5 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/BatteryView.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/BatteryView.kt @@ -24,11 +24,11 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.imageResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import me.kavishdevar.aln.AirPodsNotifications -import me.kavishdevar.aln.AirPodsService -import me.kavishdevar.aln.Battery -import me.kavishdevar.aln.BatteryComponent -import me.kavishdevar.aln.BatteryStatus +import me.kavishdevar.aln.utils.AirPodsNotifications +import me.kavishdevar.aln.services.AirPodsService +import me.kavishdevar.aln.utils.Battery +import me.kavishdevar.aln.utils.BatteryComponent +import me.kavishdevar.aln.utils.BatteryStatus import me.kavishdevar.aln.R @Composable diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/ConversationalAwarenessSwitch.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/ConversationalAwarenessSwitch.kt index b151cea..ed37eaa 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/ConversationalAwarenessSwitch.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/ConversationalAwarenessSwitch.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun ConversationalAwarenessSwitch(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/IndependentToggle.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/IndependentToggle.kt index 56cb5e2..8a2b283 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/IndependentToggle.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/IndependentToggle.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun IndependentToggle(name: String, service: AirPodsService, functionName: String, sharedPreferences: SharedPreferences, default: Boolean = false) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/LoudSoundReductionSwitch.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/LoudSoundReductionSwitch.kt index 269467b..fa41362 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/LoudSoundReductionSwitch.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/LoudSoundReductionSwitch.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun LoudSoundReductionSwitch(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlButton.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlButton.kt index 34ddb24..f7758aa 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlButton.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlButton.kt @@ -1,6 +1,5 @@ package me.kavishdevar.aln.composables -import me.kavishdevar.aln.R import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -20,6 +19,7 @@ import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.res.imageResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import me.kavishdevar.aln.R @Composable fun NoiseControlButton( diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlSettings.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlSettings.kt index e9389ce..ce0811b 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlSettings.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/NoiseControlSettings.kt @@ -34,9 +34,9 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsNotifications -import me.kavishdevar.aln.AirPodsService -import me.kavishdevar.aln.NoiseControlMode +import me.kavishdevar.aln.utils.AirPodsNotifications +import me.kavishdevar.aln.services.AirPodsService +import me.kavishdevar.aln.utils.NoiseControlMode import me.kavishdevar.aln.R @SuppressLint("UnspecifiedRegisterReceiverFlag") diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/PersonalizedVolumeSwitch.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/PersonalizedVolumeSwitch.kt index 26f3699..8301840 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/PersonalizedVolumeSwitch.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/PersonalizedVolumeSwitch.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun PersonalizedVolumeSwitch(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/SinglePodANCSwitch.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/SinglePodANCSwitch.kt index b726cc9..4634a8c 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/SinglePodANCSwitch.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/SinglePodANCSwitch.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun SinglePodANCSwitch(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/ToneVolumeSlider.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/ToneVolumeSlider.kt index 8b9ad21..21b4639 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/ToneVolumeSlider.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/ToneVolumeSlider.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService import me.kavishdevar.aln.R import kotlin.math.roundToInt diff --git a/android/app/src/main/java/me/kavishdevar/aln/composables/VolumeControlSwitch.kt b/android/app/src/main/java/me/kavishdevar/aln/composables/VolumeControlSwitch.kt index 5199e50..899042b 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/composables/VolumeControlSwitch.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/composables/VolumeControlSwitch.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService @Composable fun VolumeControlSwitch(service: AirPodsService, sharedPreferences: SharedPreferences) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/receivers/BootReceiver.kt b/android/app/src/main/java/me/kavishdevar/aln/receivers/BootReceiver.kt index ac67456..d7283f5 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/receivers/BootReceiver.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/receivers/BootReceiver.kt @@ -3,7 +3,7 @@ package me.kavishdevar.aln.receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.services.AirPodsService class BootReceiver: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/screens/AirPodsSettingsScreen.kt b/android/app/src/main/java/me/kavishdevar/aln/screens/AirPodsSettingsScreen.kt index d232681..c3ca114 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/screens/AirPodsSettingsScreen.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/screens/AirPodsSettingsScreen.kt @@ -14,8 +14,13 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Refresh import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults @@ -33,6 +38,8 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign @@ -46,8 +53,7 @@ import dev.chrisbanes.haze.haze import dev.chrisbanes.haze.hazeChild import dev.chrisbanes.haze.materials.CupertinoMaterials import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi -import me.kavishdevar.aln.AirPodsNotifications -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.R import me.kavishdevar.aln.composables.AccessibilitySettings import me.kavishdevar.aln.composables.AudioSettings import me.kavishdevar.aln.composables.BatteryView @@ -56,7 +62,10 @@ import me.kavishdevar.aln.composables.NavigationButton import me.kavishdevar.aln.composables.NoiseControlSettings import me.kavishdevar.aln.composables.PressAndHoldSettings import me.kavishdevar.aln.composables.StyledTextField +import me.kavishdevar.aln.services.AirPodsService +import me.kavishdevar.aln.services.ServiceManager import me.kavishdevar.aln.ui.theme.ALNTheme +import me.kavishdevar.aln.utils.AirPodsNotifications @OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class) @SuppressLint("MissingPermission", "NewApi") @@ -88,7 +97,13 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService, CenterAlignedTopAppBar( title = { Text( - text = deviceName.text + text = deviceName.text, + style = TextStyle( + fontSize = 20.sp, + fontWeight = FontWeight.Medium, + color = if (darkMode) Color.White else Color.Black, + fontFamily = FontFamily(Font(R.font.sf_pro)) + ) ) }, modifier = Modifier @@ -116,23 +131,23 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService, colors = TopAppBarDefaults.centerAlignedTopAppBarColors( containerColor = Color.Transparent ), -// actions = { -// val context = LocalContext.current -// IconButton( -// onClick = { -// ServiceManager.restartService(context) -// }, -// colors = IconButtonDefaults.iconButtonColors( -// containerColor = Color.Transparent, -// contentColor = if (isSystemInDarkTheme()) Color.White else Color.Black -// ) -// ) { -// Icon( -// imageVector = Icons.Default.Refresh, -// contentDescription = "Settings", -// ) -// } -// } + actions = { + val context = LocalContext.current + IconButton( + onClick = { + ServiceManager.restartService(context) + }, + colors = IconButtonDefaults.iconButtonColors( + containerColor = Color.Transparent, + contentColor = if (isSystemInDarkTheme()) Color.White else Color.Black + ) + ) { + Icon( + imageVector = Icons.Default.Refresh, + contentDescription = "Settings", + ) + } + } ) } ) { paddingValues -> @@ -228,7 +243,8 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService, style = TextStyle( fontSize = 24.sp, fontWeight = FontWeight.Medium, - color = if (isSystemInDarkTheme()) Color.White else Color.Black + color = if (isSystemInDarkTheme()) Color.White else Color.Black, + fontFamily = FontFamily(Font(R.font.sf_pro)) ), textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth() @@ -239,7 +255,8 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService, style = TextStyle( fontSize = 16.sp, fontWeight = FontWeight.Light, - color = if (isSystemInDarkTheme()) Color.White else Color.Black + color = if (isSystemInDarkTheme()) Color.White else Color.Black, + fontFamily = FontFamily(Font(R.font.sf_pro)) ), textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth() @@ -253,9 +270,13 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService, @Preview @Composable fun AirPodsSettingsScreenPreview() { - ALNTheme ( - darkTheme = true + Column ( + modifier = Modifier.height(2000.dp) ) { - AirPodsSettingsScreen(dev = null, service = AirPodsService(), navController = rememberNavController(), isConnected = true) + ALNTheme ( + darkTheme = true + ) { + AirPodsSettingsScreen(dev = null, service = AirPodsService(), navController = rememberNavController(), isConnected = true) + } } } \ No newline at end of file diff --git a/android/app/src/main/java/me/kavishdevar/aln/screens/DebugScreen.kt b/android/app/src/main/java/me/kavishdevar/aln/screens/DebugScreen.kt index 5afdda5..42f75e9 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/screens/DebugScreen.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/screens/DebugScreen.kt @@ -61,8 +61,8 @@ import dev.chrisbanes.haze.haze import dev.chrisbanes.haze.hazeChild import dev.chrisbanes.haze.materials.CupertinoMaterials import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi -import me.kavishdevar.aln.AirPodsNotifications -import me.kavishdevar.aln.AirPodsService +import me.kavishdevar.aln.utils.AirPodsNotifications +import me.kavishdevar.aln.services.AirPodsService import me.kavishdevar.aln.R @OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) diff --git a/android/app/src/main/java/me/kavishdevar/aln/screens/PressAndHoldSettingsScreen.kt b/android/app/src/main/java/me/kavishdevar/aln/screens/PressAndHoldSettingsScreen.kt index 3526286..9e2b650 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/screens/PressAndHoldSettingsScreen.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/screens/PressAndHoldSettingsScreen.kt @@ -45,7 +45,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController import me.kavishdevar.aln.R -import me.kavishdevar.aln.ServiceManager +import me.kavishdevar.aln.services.ServiceManager @Composable() fun RightDivider() { diff --git a/android/app/src/main/java/me/kavishdevar/aln/services/AirPodsQSService.kt b/android/app/src/main/java/me/kavishdevar/aln/services/AirPodsQSService.kt index 89ce7e1..3f998cf 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/services/AirPodsQSService.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/services/AirPodsQSService.kt @@ -8,9 +8,8 @@ import android.content.IntentFilter import android.service.quicksettings.Tile import android.service.quicksettings.TileService import android.util.Log -import me.kavishdevar.aln.AirPodsNotifications -import me.kavishdevar.aln.NoiseControlMode -import me.kavishdevar.aln.ServiceManager +import me.kavishdevar.aln.utils.AirPodsNotifications +import me.kavishdevar.aln.utils.NoiseControlMode class AirPodsQSService: TileService() { private val ancModes = listOf(NoiseControlMode.NOISE_CANCELLATION.name, NoiseControlMode.TRANSPARENCY.name, NoiseControlMode.ADAPTIVE.name) diff --git a/android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt b/android/app/src/main/java/me/kavishdevar/aln/services/AirPodsService.kt similarity index 96% rename from android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt rename to android/app/src/main/java/me/kavishdevar/aln/services/AirPodsService.kt index 52d621d..0dde930 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/AirPodsService.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/services/AirPodsService.kt @@ -1,4 +1,4 @@ -package me.kavishdevar.aln +package me.kavishdevar.aln.services import android.annotation.SuppressLint import android.app.Notification @@ -25,6 +25,14 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import me.kavishdevar.aln.utils.AirPodsNotifications +import me.kavishdevar.aln.utils.Battery +import me.kavishdevar.aln.utils.BatteryComponent +import me.kavishdevar.aln.utils.BatteryStatus +import me.kavishdevar.aln.utils.Enums +import me.kavishdevar.aln.utils.LongPressPackets +import me.kavishdevar.aln.R +import me.kavishdevar.aln.utils.Window import me.kavishdevar.aln.utils.MediaController import org.lsposed.hiddenapibypass.HiddenApiBypass @@ -38,11 +46,11 @@ object ServiceManager { fun setService(service: AirPodsService?) { this.service = service } -// @Synchronized -// fun restartService(context: Context) { -// service?.stopSelf() -// context.startService(Intent(context, AirPodsService::class.java)) -// } + @Synchronized + fun restartService(context: Context) { + service?.stopSelf() + context.startService(Intent(context, AirPodsService::class.java)) + } } @Suppress("unused") @@ -84,7 +92,7 @@ class AirPodsService: Service() { } val uuid = ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a") if (bluetoothDevice.uuids.contains(uuid)) { - val intent = Intent(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED) + val intent = Intent(AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED) intent.putExtra("name", name) intent.putExtra("device", bluetoothDevice) context?.sendBroadcast(intent) @@ -94,7 +102,7 @@ class AirPodsService: Service() { || BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED == action ) { context?.sendBroadcast( - Intent(AirPodsNotifications.AIRPODS_DISCONNECTED) + Intent(AirPodsNotifications.Companion.AIRPODS_DISCONNECTED) ) } } @@ -195,7 +203,6 @@ class AirPodsService: Service() { .build() } - // Notify the NotificationManager with the same ID notificationManager.notify(1, updatedNotification) } @@ -219,11 +226,12 @@ class AirPodsService: Service() { addAction("android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") addAction("android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED") } + registerReceiver(bluetoothReceiver, serviceIntentFilter, RECEIVER_EXPORTED) connectionReceiver = object: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { - if (intent?.action == AirPodsNotifications.AIRPODS_CONNECTION_DETECTED) { + if (intent?.action == AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED) { val name = this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE) .getString("name", device?.name) Log.d("AirPodsService", "$name connected") @@ -232,7 +240,7 @@ class AirPodsService: Service() { connectToSocket(device!!) updateNotificationContent(true, name.toString(), batteryNotification.getBattery()) } - else if (intent?.action == AirPodsNotifications.AIRPODS_DISCONNECTED) { + else if (intent?.action == AirPodsNotifications.Companion.AIRPODS_DISCONNECTED) { device = null isConnected = false popupShown = false @@ -242,8 +250,8 @@ class AirPodsService: Service() { } val deviceIntentFilter = IntentFilter().apply { - addAction(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED) - addAction(AirPodsNotifications.AIRPODS_DISCONNECTED) + addAction(AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED) + addAction(AirPodsNotifications.Companion.AIRPODS_DISCONNECTED) } registerReceiver(connectionReceiver, deviceIntentFilter, RECEIVER_EXPORTED) @@ -257,7 +265,7 @@ class AirPodsService: Service() { if (connectedDevices.isNotEmpty()) { connectToSocket(device) this@AirPodsService.sendBroadcast( - Intent(AirPodsNotifications.AIRPODS_CONNECTED) + Intent(AirPodsNotifications.Companion.AIRPODS_CONNECTED) ) } } @@ -348,7 +356,7 @@ class AirPodsService: Service() { it.outputStream.flush() delay(200) sendBroadcast( - Intent(AirPodsNotifications.AIRPODS_CONNECTED) + Intent(AirPodsNotifications.Companion.AIRPODS_CONNECTED) .putExtra("device", device) ) @@ -362,7 +370,7 @@ class AirPodsService: Service() { var data: ByteArray = byteArrayOf() if (bytesRead > 0) { data = buffer.copyOfRange(0, bytesRead) - sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DATA).apply { + sendBroadcast(Intent(AirPodsNotifications.Companion.AIRPODS_DATA).apply { putExtra("data", buffer.copyOfRange(0, bytesRead)) }) val bytes = buffer.copyOfRange(0, bytesRead) @@ -371,14 +379,14 @@ class AirPodsService: Service() { } else if (bytesRead == -1) { Log.d("AirPods Service", "Socket closed (bytesRead = -1)") // socket.close() - sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) + sendBroadcast(Intent(AirPodsNotifications.Companion.AIRPODS_DISCONNECTED)) return@launch } var inEar = false var inEarData = listOf() if (earDetectionNotification.isEarDetectionData(data)) { earDetectionNotification.setStatus(data) - sendBroadcast(Intent(AirPodsNotifications.EAR_DETECTION_DATA).apply { + sendBroadcast(Intent(AirPodsNotifications.Companion.EAR_DETECTION_DATA).apply { val list = earDetectionNotification.status val bytes = ByteArray(2) bytes[0] = list[0] @@ -463,7 +471,7 @@ class AirPodsService: Service() { } val earIntentFilter = - IntentFilter(AirPodsNotifications.EAR_DETECTION_DATA) + IntentFilter(AirPodsNotifications.Companion.EAR_DETECTION_DATA) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { this@AirPodsService.registerReceiver( earReceiver, earIntentFilter, @@ -477,13 +485,13 @@ class AirPodsService: Service() { } } else if (ancNotification.isANCData(data)) { ancNotification.setStatus(data) - sendBroadcast(Intent(AirPodsNotifications.ANC_DATA).apply { + sendBroadcast(Intent(AirPodsNotifications.Companion.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 { + sendBroadcast(Intent(AirPodsNotifications.Companion.BATTERY_DATA).apply { putParcelableArrayListExtra( "data", ArrayList(batteryNotification.getBattery()) @@ -513,7 +521,7 @@ class AirPodsService: Service() { ) ) { conversationAwarenessNotification.setData(data) - sendBroadcast(Intent(AirPodsNotifications.CA_DATA).apply { + sendBroadcast(Intent(AirPodsNotifications.Companion.CA_DATA).apply { putExtra("data", conversationAwarenessNotification.status) }) @@ -535,7 +543,7 @@ class AirPodsService: Service() { Log.d("AirPods Service", "Socket closed") isConnected = false socket.close() - sendBroadcast(Intent(AirPodsNotifications.AIRPODS_DISCONNECTED)) + sendBroadcast(Intent(AirPodsNotifications.Companion.AIRPODS_DISCONNECTED)) } } } catch (e: Exception) { diff --git a/android/app/src/main/java/me/kavishdevar/aln/Packets.kt b/android/app/src/main/java/me/kavishdevar/aln/utils/Packets.kt similarity index 99% rename from android/app/src/main/java/me/kavishdevar/aln/Packets.kt rename to android/app/src/main/java/me/kavishdevar/aln/utils/Packets.kt index a0a4154..4a86361 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/Packets.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/utils/Packets.kt @@ -1,6 +1,6 @@ @file:Suppress("unused") -package me.kavishdevar.aln +package me.kavishdevar.aln.utils import android.os.Parcelable import kotlinx.parcelize.Parcelize diff --git a/android/app/src/main/java/me/kavishdevar/aln/Window.kt b/android/app/src/main/java/me/kavishdevar/aln/utils/Window.kt similarity index 99% rename from android/app/src/main/java/me/kavishdevar/aln/Window.kt rename to android/app/src/main/java/me/kavishdevar/aln/utils/Window.kt index 3e06d60..9deee44 100644 --- a/android/app/src/main/java/me/kavishdevar/aln/Window.kt +++ b/android/app/src/main/java/me/kavishdevar/aln/utils/Window.kt @@ -1,4 +1,4 @@ -package me.kavishdevar.aln +package me.kavishdevar.aln.utils import android.animation.Animator import android.animation.AnimatorListenerAdapter @@ -22,7 +22,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.MainScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import java.lang.Exception +import me.kavishdevar.aln.R @SuppressLint("InflateParams", "ClickableViewAccessibility") class Window (context: Context) { diff --git a/android/app/src/main/res/drawable-v21/app_widget_inner_view_background.xml b/android/app/src/main/res/drawable-v21/app_widget_inner_view_background.xml index 007e287..11a09f9 100644 --- a/android/app/src/main/res/drawable-v21/app_widget_inner_view_background.xml +++ b/android/app/src/main/res/drawable-v21/app_widget_inner_view_background.xml @@ -4,7 +4,6 @@ appWidgetInnerRadius attribute value --> - \ No newline at end of file diff --git a/android/app/src/main/res/layout-v31/battery_widget.xml b/android/app/src/main/res/layout-v31/battery_widget.xml new file mode 100644 index 0000000..09225ee --- /dev/null +++ b/android/app/src/main/res/layout-v31/battery_widget.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/battery_widget.xml b/android/app/src/main/res/layout/battery_widget.xml index 5941dd5..dec5db9 100644 --- a/android/app/src/main/res/layout/battery_widget.xml +++ b/android/app/src/main/res/layout/battery_widget.xml @@ -1,19 +1,74 @@ + + - + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml index 02f8b09..7a2a42e 100644 --- a/android/app/src/main/res/values-night/colors.xml +++ b/android/app/src/main/res/values-night/colors.xml @@ -2,4 +2,6 @@ #1C1B1E @color/white + #1C1B1E + @color/white \ No newline at end of file diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 1f8c039..2779d25 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -4,8 +4,6 @@ #FFFFFFFF #FFFFFF @color/black - #FFE1F5FE - #FF81D4FA - #FF039BE5 - #FF01579B + #87FFFFFF + @color/black \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 6a9ee85..3b28a1d 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,7 +1,5 @@ ALN GATT Testing - EXAMPLE - Add widget - This is an app widget description + See your AirPods battery status right from your home screen! \ No newline at end of file diff --git a/android/app/src/main/res/values/themes.xml b/android/app/src/main/res/values/themes.xml index 65fdb74..a4815df 100644 --- a/android/app/src/main/res/values/themes.xml +++ b/android/app/src/main/res/values/themes.xml @@ -5,12 +5,12 @@