mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-10 19:52:24 +00:00
fix for pre-tiramisu android versions
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package me.kavishdevar.aln
|
package me.kavishdevar.aln
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.bluetooth.BluetoothDevice
|
import android.bluetooth.BluetoothDevice
|
||||||
import android.bluetooth.BluetoothDevice.TRANSPORT_LE
|
import android.bluetooth.BluetoothDevice.TRANSPORT_LE
|
||||||
@@ -25,11 +26,13 @@ import android.bluetooth.BluetoothGatt
|
|||||||
import android.bluetooth.BluetoothGattCallback
|
import android.bluetooth.BluetoothGattCallback
|
||||||
import android.bluetooth.BluetoothGattCharacteristic
|
import android.bluetooth.BluetoothGattCharacteristic
|
||||||
import android.bluetooth.BluetoothManager
|
import android.bluetooth.BluetoothManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -49,7 +52,7 @@ import org.lsposed.hiddenapibypass.HiddenApiBypass
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class CustomDevice : ComponentActivity() {
|
class CustomDevice : ComponentActivity() {
|
||||||
@SuppressLint("MissingPermission", "CoroutineCreationDuringComposition", "NewApi")
|
@SuppressLint("MissingPermission", "CoroutineCreationDuringComposition")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
@@ -152,7 +155,7 @@ class CustomDevice : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission", "NewApi")
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
fun sendWriteRequest(
|
fun sendWriteRequest(
|
||||||
gatt: BluetoothGatt,
|
gatt: BluetoothGatt,
|
||||||
characteristicUuid: String,
|
characteristicUuid: String,
|
||||||
@@ -177,6 +180,10 @@ fun sendWriteRequest(
|
|||||||
|
|
||||||
|
|
||||||
// Send the write request
|
// Send the write request
|
||||||
val success = gatt.writeCharacteristic(characteristic, value, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT)
|
val success = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
gatt.writeCharacteristic(characteristic, value, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT)
|
||||||
|
} else {
|
||||||
|
gatt.writeCharacteristic(characteristic)
|
||||||
|
}
|
||||||
Log.d("GATT", "Write request sent $success to UUID: $characteristicUuid")
|
Log.d("GATT", "Write request sent $success to UUID: $characteristicUuid")
|
||||||
}
|
}
|
||||||
@@ -22,9 +22,11 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Context.RECEIVER_EXPORTED
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -110,7 +112,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission", "InlinedApi")
|
@SuppressLint("MissingPermission", "InlinedApi", "UnspecifiedRegisterReceiverFlag")
|
||||||
@OptIn(ExperimentalPermissionsApi::class)
|
@OptIn(ExperimentalPermissionsApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Main() {
|
fun Main() {
|
||||||
@@ -146,7 +148,12 @@ fun Main() {
|
|||||||
addAction(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
|
addAction(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
|
||||||
}
|
}
|
||||||
Log.d("MainActivity", "Registering Receiver")
|
Log.d("MainActivity", "Registering Receiver")
|
||||||
context.registerReceiver(connectionStatusReceiver, filter, Context.RECEIVER_EXPORTED)
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
context.registerReceiver(connectionStatusReceiver, filter, RECEIVER_EXPORTED)
|
||||||
|
} else {
|
||||||
|
context.registerReceiver(connectionStatusReceiver, filter)
|
||||||
|
}
|
||||||
Log.d("MainActivity", "Registered Receiver")
|
Log.d("MainActivity", "Registered Receiver")
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
|
|||||||
@@ -23,20 +23,29 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
|
import androidx.compose.foundation.gestures.draggable
|
||||||
|
import androidx.compose.foundation.gestures.rememberDraggableState
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.VerticalDivider
|
import androidx.compose.material3.VerticalDivider
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -50,19 +59,36 @@ import androidx.compose.ui.text.TextStyle
|
|||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import me.kavishdevar.aln.R
|
import me.kavishdevar.aln.R
|
||||||
import me.kavishdevar.aln.services.AirPodsService
|
import me.kavishdevar.aln.services.AirPodsService
|
||||||
import me.kavishdevar.aln.utils.AirPodsNotifications
|
import me.kavishdevar.aln.utils.AirPodsNotifications
|
||||||
import me.kavishdevar.aln.utils.NoiseControlMode
|
import me.kavishdevar.aln.utils.NoiseControlMode
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@SuppressLint("UnspecifiedRegisterReceiverFlag")
|
@SuppressLint("UnspecifiedRegisterReceiverFlag")
|
||||||
@Composable
|
@Composable
|
||||||
fun NoiseControlSettings(service: AirPodsService) {
|
fun NoiseControlSettings(service: AirPodsService) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val sharedPreferences = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
val sharedPreferences = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||||
val offListeningMode = sharedPreferences.getBoolean("off_listening_mode", true)
|
val offListeningMode = remember { mutableStateOf(sharedPreferences.getBoolean("off_listening_mode", true)) }
|
||||||
|
|
||||||
|
val preferenceChangeListener = remember {
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
|
||||||
|
if (key == "off_listening_mode") {
|
||||||
|
offListeningMode.value = sharedPreferences.getBoolean("off_listening_mode", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
|
||||||
|
onDispose {
|
||||||
|
sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val isDarkTheme = isSystemInDarkTheme()
|
val isDarkTheme = isSystemInDarkTheme()
|
||||||
val backgroundColor = if (isDarkTheme) Color(0xFF1C1C1E) else Color(0xFFE3E3E8)
|
val backgroundColor = if (isDarkTheme) Color(0xFF1C1C1E) else Color(0xFFE3E3E8)
|
||||||
@@ -71,18 +97,28 @@ fun NoiseControlSettings(service: AirPodsService) {
|
|||||||
val selectedBackground = if (isDarkTheme) Color(0xFF5C5A5F) else Color(0xFFFFFFFF)
|
val selectedBackground = if (isDarkTheme) Color(0xFF5C5A5F) else Color(0xFFFFFFFF)
|
||||||
|
|
||||||
val noiseControlMode = remember { mutableStateOf(NoiseControlMode.OFF) }
|
val noiseControlMode = remember { mutableStateOf(NoiseControlMode.OFF) }
|
||||||
|
val selectedOffset = remember { mutableFloatStateOf(0f) }
|
||||||
|
val animatedOffset = animateFloatAsState(targetValue = selectedOffset.floatValue)
|
||||||
|
|
||||||
val d1a = remember { mutableFloatStateOf(0f) }
|
val d1a = remember { mutableFloatStateOf(0f) }
|
||||||
val d2a = remember { mutableFloatStateOf(0f) }
|
val d2a = remember { mutableFloatStateOf(0f) }
|
||||||
val d3a = remember { mutableFloatStateOf(0f) }
|
val d3a = remember { mutableFloatStateOf(0f) }
|
||||||
|
|
||||||
|
val boxWidth = 200.dp.value
|
||||||
|
|
||||||
fun onModeSelected(mode: NoiseControlMode, received: Boolean = false) {
|
fun onModeSelected(mode: NoiseControlMode, received: Boolean = false) {
|
||||||
if (!received && !offListeningMode && mode == NoiseControlMode.OFF) {
|
if (!received && !offListeningMode.value && mode == NoiseControlMode.OFF) {
|
||||||
noiseControlMode.value = NoiseControlMode.ADAPTIVE
|
noiseControlMode.value = NoiseControlMode.ADAPTIVE
|
||||||
} else {
|
} else {
|
||||||
noiseControlMode.value = mode
|
noiseControlMode.value = mode
|
||||||
}
|
}
|
||||||
if (!received) service.setANCMode(mode.ordinal + 1)
|
if (!received) service.setANCMode(mode.ordinal + 1)
|
||||||
|
selectedOffset.floatValue = when (noiseControlMode.value) {
|
||||||
|
NoiseControlMode.NOISE_CANCELLATION -> 3 * boxWidth
|
||||||
|
NoiseControlMode.OFF -> 0f
|
||||||
|
NoiseControlMode.ADAPTIVE -> 2 * boxWidth
|
||||||
|
NoiseControlMode.TRANSPARENCY -> 1 * boxWidth
|
||||||
|
}
|
||||||
when (noiseControlMode.value) {
|
when (noiseControlMode.value) {
|
||||||
NoiseControlMode.NOISE_CANCELLATION -> {
|
NoiseControlMode.NOISE_CANCELLATION -> {
|
||||||
d1a.floatValue = 1f
|
d1a.floatValue = 1f
|
||||||
@@ -107,6 +143,15 @@ fun NoiseControlSettings(service: AirPodsService) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(noiseControlMode.value) {
|
||||||
|
selectedOffset.value = when (noiseControlMode.value) {
|
||||||
|
NoiseControlMode.NOISE_CANCELLATION -> 3 * boxWidth
|
||||||
|
NoiseControlMode.OFF -> 0f
|
||||||
|
NoiseControlMode.ADAPTIVE -> 2 * boxWidth
|
||||||
|
NoiseControlMode.TRANSPARENCY -> 1 * boxWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val noiseControlReceiver = remember {
|
val noiseControlReceiver = remember {
|
||||||
object : BroadcastReceiver() {
|
object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
@@ -154,13 +199,26 @@ fun NoiseControlSettings(service: AirPodsService) {
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(75.dp)
|
.height(75.dp)
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
|
.draggable(
|
||||||
|
orientation = Orientation.Horizontal,
|
||||||
|
state = rememberDraggableState { delta ->
|
||||||
|
selectedOffset.floatValue = (selectedOffset.floatValue + delta).coerceIn(0f, 3 * boxWidth)
|
||||||
|
}
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(backgroundColor, RoundedCornerShape(14.dp))
|
.background(backgroundColor, RoundedCornerShape(14.dp))
|
||||||
) {
|
) {
|
||||||
if (offListeningMode) {
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.offset { IntOffset(animatedOffset.value.roundToInt(), 0) }
|
||||||
|
.width(boxWidth.dp)
|
||||||
|
.height(75.dp)
|
||||||
|
.background(selectedBackground, RoundedCornerShape(14.dp))
|
||||||
|
)
|
||||||
|
if (offListeningMode.value) {
|
||||||
NoiseControlButton(
|
NoiseControlButton(
|
||||||
icon = ImageBitmap.imageResource(R.drawable.noise_cancellation),
|
icon = ImageBitmap.imageResource(R.drawable.noise_cancellation),
|
||||||
onClick = { onModeSelected(NoiseControlMode.OFF) },
|
onClick = { onModeSelected(NoiseControlMode.OFF) },
|
||||||
@@ -219,7 +277,7 @@ fun NoiseControlSettings(service: AirPodsService) {
|
|||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
.padding(top = 1.dp)
|
.padding(top = 1.dp)
|
||||||
) {
|
) {
|
||||||
if (offListeningMode) {
|
if (offListeningMode.value) {
|
||||||
Text(
|
Text(
|
||||||
text = "Off",
|
text = "Off",
|
||||||
style = TextStyle(fontSize = 12.sp, color = textColor),
|
style = TextStyle(fontSize = 12.sp, color = textColor),
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ import me.kavishdevar.aln.ui.theme.ALNTheme
|
|||||||
import me.kavishdevar.aln.utils.AirPodsNotifications
|
import me.kavishdevar.aln.utils.AirPodsNotifications
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class)
|
||||||
@SuppressLint("MissingPermission", "NewApi")
|
@SuppressLint("MissingPermission")
|
||||||
@Composable
|
@Composable
|
||||||
fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
|
fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
|
||||||
navController: NavController, isConnected: Boolean) {
|
navController: NavController, isConnected: Boolean) {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ import me.kavishdevar.aln.services.AirPodsService
|
|||||||
import me.kavishdevar.aln.utils.AirPodsNotifications
|
import me.kavishdevar.aln.utils.AirPodsNotifications
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
||||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "UnspecifiedRegisterReceiverFlag")
|
||||||
@Composable
|
@Composable
|
||||||
fun DebugScreen(navController: NavController) {
|
fun DebugScreen(navController: NavController) {
|
||||||
val hazeState = remember { HazeState() }
|
val hazeState = remember { HazeState() }
|
||||||
@@ -158,6 +158,8 @@ fun DebugScreen(navController: NavController) {
|
|||||||
val intentFilter = IntentFilter(AirPodsNotifications.Companion.AIRPODS_DATA)
|
val intentFilter = IntentFilter(AirPodsNotifications.Companion.AIRPODS_DATA)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
context.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED)
|
context.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED)
|
||||||
|
} else {
|
||||||
|
context.registerReceiver(receiver, intentFilter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
|
import android.os.Build
|
||||||
import android.service.quicksettings.Tile
|
import android.service.quicksettings.Tile
|
||||||
import android.service.quicksettings.TileService
|
import android.service.quicksettings.TileService
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -35,7 +36,7 @@ class AirPodsQSService: TileService() {
|
|||||||
private lateinit var ancStatusReceiver: BroadcastReceiver
|
private lateinit var ancStatusReceiver: BroadcastReceiver
|
||||||
private lateinit var availabilityReceiver: BroadcastReceiver
|
private lateinit var availabilityReceiver: BroadcastReceiver
|
||||||
|
|
||||||
@SuppressLint("InlinedApi")
|
@SuppressLint("InlinedApi", "UnspecifiedRegisterReceiverFlag")
|
||||||
override fun onStartListening() {
|
override fun onStartListening() {
|
||||||
super.onStartListening()
|
super.onStartListening()
|
||||||
currentModeIndex = (ServiceManager.getService()?.getANC()?.minus(1)) ?: -1
|
currentModeIndex = (ServiceManager.getService()?.getANC()?.minus(1)) ?: -1
|
||||||
@@ -77,9 +78,17 @@ class AirPodsQSService: TileService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerReceiver(ancStatusReceiver,
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
IntentFilter(AirPodsNotifications.Companion.ANC_DATA), RECEIVER_EXPORTED)
|
registerReceiver(
|
||||||
|
ancStatusReceiver,
|
||||||
|
IntentFilter(AirPodsNotifications.Companion.ANC_DATA), RECEIVER_EXPORTED
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
registerReceiver(
|
||||||
|
ancStatusReceiver,
|
||||||
|
IntentFilter(AirPodsNotifications.Companion.ANC_DATA)
|
||||||
|
)
|
||||||
|
}
|
||||||
qsTile.state = if (ServiceManager.getService()?.isConnected == true) Tile.STATE_ACTIVE else Tile.STATE_UNAVAILABLE
|
qsTile.state = if (ServiceManager.getService()?.isConnected == true) Tile.STATE_ACTIVE else Tile.STATE_UNAVAILABLE
|
||||||
val ancIndex = ServiceManager.getService()?.getANC()
|
val ancIndex = ServiceManager.getService()?.getANC()
|
||||||
currentModeIndex = if (ancIndex != null) { if (ancIndex == 2) 0 else if (ancIndex == 3) 1 else if (ancIndex == 4) 2 else 2 } else 0
|
currentModeIndex = if (ancIndex != null) { if (ancIndex == 2) 0 else if (ancIndex == 3) 1 else if (ancIndex == 4) 2 else 2 } else 0
|
||||||
|
|||||||
@@ -107,10 +107,14 @@ class AirPodsService: Service() {
|
|||||||
|
|
||||||
@Suppress("ClassName")
|
@Suppress("ClassName")
|
||||||
private object bluetoothReceiver: BroadcastReceiver() {
|
private object bluetoothReceiver: BroadcastReceiver() {
|
||||||
@SuppressLint("NewApi", "MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onReceive(context: Context?, intent: Intent) {
|
override fun onReceive(context: Context?, intent: Intent) {
|
||||||
val bluetoothDevice =
|
val bluetoothDevice =
|
||||||
intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE", BluetoothDevice::class.java)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE", BluetoothDevice::class.java)
|
||||||
|
} else {
|
||||||
|
intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE") as BluetoothDevice?
|
||||||
|
}
|
||||||
val action = intent.action
|
val action = intent.action
|
||||||
val context = context?.applicationContext
|
val context = context?.applicationContext
|
||||||
val name = context?.getSharedPreferences("settings", MODE_PRIVATE)?.getString("name", bluetoothDevice?.name)
|
val name = context?.getSharedPreferences("settings", MODE_PRIVATE)?.getString("name", bluetoothDevice?.name)
|
||||||
@@ -148,7 +152,7 @@ class AirPodsService: Service() {
|
|||||||
notificationManager.createNotificationChannel(notificationChannel)
|
notificationManager.createNotificationChannel(notificationChannel)
|
||||||
val notification = NotificationCompat.Builder(this, "background_service_status")
|
val notification = NotificationCompat.Builder(this, "background_service_status")
|
||||||
.setSmallIcon(R.drawable.airpods)
|
.setSmallIcon(R.drawable.airpods)
|
||||||
.setContentTitle("AirPods are not connected")
|
.setContentTitle("AirPods not connected")
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
@@ -261,24 +265,24 @@ class AirPodsService: Service() {
|
|||||||
|
|
||||||
updatedNotification = NotificationCompat.Builder(this, "background_service_status")
|
updatedNotification = NotificationCompat.Builder(this, "background_service_status")
|
||||||
.setSmallIcon(R.drawable.airpods)
|
.setSmallIcon(R.drawable.airpods)
|
||||||
.setContentTitle("""AirPods –${batteryList?.find { it.component == BatteryComponent.LEFT }?.let {
|
.setContentTitle("""$airpodsName –${batteryList?.find { it.component == BatteryComponent.LEFT }?.let {
|
||||||
// if (it.status != BatteryStatus.DISCONNECTED) {
|
if (it.status != BatteryStatus.DISCONNECTED) {
|
||||||
" L:${if (it.status == BatteryStatus.CHARGING) "⚡" else ""} ${it.level}%"
|
" L:${if (it.status == BatteryStatus.CHARGING) "⚡" else ""} ${it.level}%"
|
||||||
// } else {
|
} else {
|
||||||
// ""
|
""
|
||||||
// }
|
}
|
||||||
} ?: ""}${batteryList?.find { it.component == BatteryComponent.RIGHT }?.let {
|
} ?: ""}${batteryList?.find { it.component == BatteryComponent.RIGHT }?.let {
|
||||||
// if (it.status != BatteryStatus.DISCONNECTED) {
|
if (it.status != BatteryStatus.DISCONNECTED) {
|
||||||
" R:${if (it.status == BatteryStatus.CHARGING) "⚡" else ""} ${it.level}%"
|
" R:${if (it.status == BatteryStatus.CHARGING) "⚡" else ""} ${it.level}%"
|
||||||
// } else {
|
} else {
|
||||||
// ""
|
""
|
||||||
// }
|
}
|
||||||
} ?: ""}${batteryList?.find { it.component == BatteryComponent.CASE }?.let {
|
} ?: ""}${batteryList?.find { it.component == BatteryComponent.CASE }?.let {
|
||||||
// if (it.status != BatteryStatus.DISCONNECTED) {
|
if (it.status != BatteryStatus.DISCONNECTED) {
|
||||||
" C:${if (it.status == BatteryStatus.CHARGING) "⚡" else ""} ${it.level}%"
|
" C:${if (it.status == BatteryStatus.CHARGING) "⚡" else ""} ${it.level}%"
|
||||||
// } else {
|
} else {
|
||||||
// ""
|
""
|
||||||
// }
|
}
|
||||||
} ?: ""}""")
|
} ?: ""}""")
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
@@ -288,7 +292,7 @@ class AirPodsService: Service() {
|
|||||||
} else {
|
} else {
|
||||||
updatedNotification = NotificationCompat.Builder(this, "background_service_status")
|
updatedNotification = NotificationCompat.Builder(this, "background_service_status")
|
||||||
.setSmallIcon(R.drawable.airpods)
|
.setSmallIcon(R.drawable.airpods)
|
||||||
.setContentTitle("AirPods are not connected")
|
.setContentTitle("AirPods not connected")
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
@@ -301,7 +305,7 @@ class AirPodsService: Service() {
|
|||||||
private lateinit var connectionReceiver: BroadcastReceiver
|
private lateinit var connectionReceiver: BroadcastReceiver
|
||||||
private lateinit var disconnectionReceiver: BroadcastReceiver
|
private lateinit var disconnectionReceiver: BroadcastReceiver
|
||||||
|
|
||||||
@SuppressLint("InlinedApi", "MissingPermission")
|
@SuppressLint("InlinedApi", "MissingPermission", "UnspecifiedRegisterReceiverFlag")
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
Log.d("AirPodsService", "Service started")
|
Log.d("AirPodsService", "Service started")
|
||||||
ServiceManager.setService(this)
|
ServiceManager.setService(this)
|
||||||
@@ -319,12 +323,20 @@ class AirPodsService: Service() {
|
|||||||
addAction("android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED")
|
addAction("android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED")
|
||||||
}
|
}
|
||||||
|
|
||||||
registerReceiver(bluetoothReceiver, serviceIntentFilter, RECEIVER_EXPORTED)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
registerReceiver(bluetoothReceiver, serviceIntentFilter, RECEIVER_EXPORTED)
|
||||||
|
} else {
|
||||||
|
registerReceiver(bluetoothReceiver, serviceIntentFilter)
|
||||||
|
}
|
||||||
|
|
||||||
connectionReceiver = object: BroadcastReceiver() {
|
connectionReceiver = object: BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
if (intent?.action == AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED) {
|
if (intent?.action == AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED) {
|
||||||
device = intent.getParcelableExtra("device", BluetoothDevice::class.java)!!
|
device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
intent.getParcelableExtra("device", BluetoothDevice::class.java)!!
|
||||||
|
} else {
|
||||||
|
intent.getParcelableExtra("device") as BluetoothDevice?
|
||||||
|
}
|
||||||
val name = this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE)
|
val name = this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE)
|
||||||
.getString("name", device?.name)
|
.getString("name", device?.name)
|
||||||
if (this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE).getString("name", null) == null) {
|
if (this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE).getString("name", null) == null) {
|
||||||
@@ -349,7 +361,11 @@ class AirPodsService: Service() {
|
|||||||
addAction(AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED)
|
addAction(AirPodsNotifications.Companion.AIRPODS_CONNECTION_DETECTED)
|
||||||
addAction(AirPodsNotifications.Companion.AIRPODS_DISCONNECTED)
|
addAction(AirPodsNotifications.Companion.AIRPODS_DISCONNECTED)
|
||||||
}
|
}
|
||||||
registerReceiver(connectionReceiver, deviceIntentFilter, RECEIVER_EXPORTED)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
registerReceiver(connectionReceiver, deviceIntentFilter, RECEIVER_EXPORTED)
|
||||||
|
} else {
|
||||||
|
registerReceiver(connectionReceiver, deviceIntentFilter)
|
||||||
|
}
|
||||||
|
|
||||||
val bluetoothAdapter = getSystemService(BluetoothManager::class.java).adapter
|
val bluetoothAdapter = getSystemService(BluetoothManager::class.java).adapter
|
||||||
bluetoothAdapter.bondedDevices.forEach { device ->
|
bluetoothAdapter.bondedDevices.forEach { device ->
|
||||||
@@ -500,7 +516,6 @@ class AirPodsService: Service() {
|
|||||||
)
|
)
|
||||||
var justEnabledA2dp = false
|
var justEnabledA2dp = false
|
||||||
earReceiver = object : BroadcastReceiver() {
|
earReceiver = object : BroadcastReceiver() {
|
||||||
@SuppressLint("NewApi")
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val data = intent.getByteArrayExtra("data")
|
val data = intent.getByteArrayExtra("data")
|
||||||
if (data != null && earDetectionEnabled) {
|
if (data != null && earDetectionEnabled) {
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ class Window (context: Context) {
|
|||||||
private val mView: View
|
private val mView: View
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@SuppressLint("NewApi")
|
|
||||||
private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams().apply {
|
private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams().apply {
|
||||||
height = WindowManager.LayoutParams.WRAP_CONTENT
|
height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
width = WindowManager.LayoutParams.MATCH_PARENT
|
width = WindowManager.LayoutParams.MATCH_PARENT
|
||||||
|
|||||||
Reference in New Issue
Block a user