mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-01-31 15:19:11 +00:00
idk what i'm doing
This commit is contained in:
@@ -22,6 +22,7 @@ import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
||||
|
||||
@@ -35,8 +36,8 @@ class AirPodsService: Service() {
|
||||
return LocalBinder()
|
||||
}
|
||||
|
||||
fun showPopup(context: Context, name: String) {
|
||||
val window = Window(context)
|
||||
fun showPopup(service: Service, name: String) {
|
||||
val window = Window(service.applicationContext)
|
||||
window.open(name, batteryNotification)
|
||||
}
|
||||
|
||||
@@ -47,6 +48,7 @@ class AirPodsService: Service() {
|
||||
intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE", BluetoothDevice::class.java)
|
||||
val action = intent.action
|
||||
val context = context?.applicationContext
|
||||
val name = context?.getSharedPreferences("settings", MODE_PRIVATE)?.getString("name", bluetoothDevice?.name)
|
||||
if (bluetoothDevice != null && action != null && !action.isEmpty()) {
|
||||
Log.d("BluetoothReceiver", "Received broadcast")
|
||||
if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
|
||||
@@ -54,7 +56,7 @@ class AirPodsService: Service() {
|
||||
if (bluetoothDevice.uuids.contains(uuid)) {
|
||||
Log.d("AirPodsService", "Service started")
|
||||
val intent = Intent(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
|
||||
intent.putExtra("name", bluetoothDevice.name)
|
||||
intent.putExtra("name", name)
|
||||
intent.putExtra("device", bluetoothDevice)
|
||||
context?.sendBroadcast(intent)
|
||||
}
|
||||
@@ -104,8 +106,9 @@ class AirPodsService: Service() {
|
||||
|
||||
registerReceiver(object: BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
showPopup(context!!, intent!!.getStringExtra("name")!!)
|
||||
device = intent.getParcelableExtra("device", BluetoothDevice::class.java)!!
|
||||
val name = this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE).getString("name", device?.name)
|
||||
device = intent?.getParcelableExtra("device", BluetoothDevice::class.java)!!
|
||||
showPopup(this@AirPodsService, name.toString())
|
||||
connectToSocket(device!!)
|
||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_CONNECTED).apply {
|
||||
putExtra("device", device)
|
||||
@@ -188,12 +191,18 @@ class AirPodsService: Service() {
|
||||
this@AirPodsService.device = device
|
||||
isConnected = true
|
||||
socket.let { it ->
|
||||
it.outputStream.write(Enums.HANDSHAKE.value)
|
||||
it.outputStream.flush()
|
||||
it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value)
|
||||
it.outputStream.flush()
|
||||
it.outputStream.write(Enums.REQUEST_NOTIFICATIONS.value)
|
||||
it.outputStream.flush()
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
it.outputStream.write(Enums.HANDSHAKE.value)
|
||||
it.outputStream.flush()
|
||||
delay(500)
|
||||
it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value)
|
||||
it.outputStream.flush()
|
||||
delay(500)
|
||||
it.outputStream.write(Enums.REQUEST_NOTIFICATIONS.value)
|
||||
it.outputStream.flush()
|
||||
Log.d("AirPodsService","This should run first")
|
||||
}
|
||||
Log.d("AirPodsService","This should run later")
|
||||
sendBroadcast(
|
||||
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
||||
.putExtra("device", device)
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Context.MODE_PRIVATE
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
@@ -82,6 +83,7 @@ import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.NavController
|
||||
import com.primex.core.ExperimentalToolkitApi
|
||||
import com.primex.core.blur.newBackgroundBlur
|
||||
import me.kavishdevar.aln.AirPodsService
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
@@ -90,7 +92,12 @@ fun BatteryView() {
|
||||
@Suppress("DEPRECATION") val batteryReceiver = remember {
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
batteryStatus.value = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getParcelableArrayListExtra("data", Battery::class.java) } else { intent.getParcelableArrayListExtra("data") }?.toList() ?: listOf()
|
||||
batteryStatus.value =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
intent.getParcelableArrayListExtra("data", Battery::class.java)
|
||||
} else {
|
||||
intent.getParcelableArrayListExtra("data")
|
||||
}?.toList() ?: listOf()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,7 +106,11 @@ fun BatteryView() {
|
||||
LaunchedEffect(context) {
|
||||
val batteryIntentFilter = IntentFilter(AirPodsNotifications.BATTERY_DATA)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
context.registerReceiver(batteryReceiver, batteryIntentFilter, Context.RECEIVER_EXPORTED)
|
||||
context.registerReceiver(
|
||||
batteryReceiver,
|
||||
batteryIntentFilter,
|
||||
Context.RECEIVER_EXPORTED
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +493,7 @@ fun AirPodsSettingsScreen(device: BluetoothDevice?, service: AirPodsService?,
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = if (device != null) device.name else "",
|
||||
text = if (device != null) LocalContext.current.getSharedPreferences("settings", MODE_PRIVATE).getString("name", device.name).toString() else "",
|
||||
color = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color.White else Color.Black,
|
||||
)
|
||||
},
|
||||
|
||||
@@ -53,9 +53,10 @@ class CustomDevice : ComponentActivity() {
|
||||
HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;")
|
||||
val manager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
|
||||
// val device: BluetoothDevice = manager.adapter.getRemoteDevice("EC:D6:F4:3D:89:B8")
|
||||
val device: BluetoothDevice = manager.adapter.getRemoteDevice("E0:90:8F:D9:94:73")
|
||||
val device: BluetoothDevice = manager.adapter.getRemoteDevice("DE:F4:C6:A3:CD:7A")
|
||||
// val socket = device.createInsecureL2capChannel(31)
|
||||
|
||||
val batteryLevel = remember { mutableStateOf("") }
|
||||
// socket.outputStream.write(byteArrayOf(0x12,0x3B,0x00,0x02, 0x00))
|
||||
// socket.outputStream.write(byteArrayOf(0x12, 0x3A, 0x00, 0x01, 0x00, 0x08,0x01))
|
||||
|
||||
@@ -66,9 +67,12 @@ class CustomDevice : ComponentActivity() {
|
||||
gatt.services.forEach { service ->
|
||||
Log.d("GATT", "Service UUID: ${service.uuid}")
|
||||
service.characteristics.forEach { characteristic ->
|
||||
Log.d("GATT", " Characteristic UUID: ${characteristic.uuid}")
|
||||
characteristic.descriptors.forEach { descriptor ->
|
||||
Log.d("GATT", " Descriptor UUID: ${descriptor.uuid}: ${gatt.readDescriptor(descriptor)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,12 +119,13 @@ class CustomDevice : ComponentActivity() {
|
||||
}
|
||||
|
||||
Button(onClick = {
|
||||
val characteristicUuid = "4f860002-943b-49ef-bed4-2f730304427a"
|
||||
val value = byteArrayOf(0x01, 0x00, 0x02)
|
||||
// val characteristicUuid = "4f860002-943b-49ef-bed4-2f730304427a"
|
||||
// val value = byteArrayOf(0x01, 0x00, 0x02)
|
||||
|
||||
// sendWriteRequest(gatt, characteristicUuid, value)
|
||||
|
||||
sendWriteRequest(gatt, characteristicUuid, value)
|
||||
}) {
|
||||
Text("Play Sound")
|
||||
Text("batteryLevel.value")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ fun Main() {
|
||||
context.registerReceiver(disconnectReceiver, IntentFilter(AirPodsNotifications.AIRPODS_DISCONNECTED),
|
||||
Context.RECEIVER_NOT_EXPORTED)
|
||||
|
||||
|
||||
// UI logic
|
||||
NavHost(
|
||||
navController = navController,
|
||||
@@ -127,7 +126,8 @@ fun Main() {
|
||||
|
||||
context.bindService(Intent(context, AirPodsService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
|
||||
|
||||
if (airPodsService.value?.isConnected == true) {
|
||||
val alreadyConnected = remember { mutableStateOf(false) }
|
||||
if (airPodsService.value?.isConnected == true && !alreadyConnected.value) {
|
||||
Log.d("ALN", "Connected")
|
||||
navController.navigate("settings")
|
||||
} else {
|
||||
|
||||
@@ -14,17 +14,19 @@ import android.view.WindowManager
|
||||
import android.view.animation.AccelerateInterpolator
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.widget.ImageButton
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.VideoView
|
||||
import androidx.lifecycle.findViewTreeLifecycleOwner
|
||||
import androidx.lifecycle.setViewTreeLifecycleOwner
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.Exception
|
||||
|
||||
class Window @SuppressLint("InflateParams") constructor(
|
||||
context: Context
|
||||
) {
|
||||
@SuppressLint("InflateParams")
|
||||
class Window (context: Context) {
|
||||
private val mView: View
|
||||
private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams(
|
||||
(context.resources.displayMetrics.widthPixels * 0.95).toInt(),
|
||||
@@ -50,6 +52,11 @@ class Window @SuppressLint("InflateParams") constructor(
|
||||
close()
|
||||
}
|
||||
|
||||
val ll = mView.findViewById<LinearLayout>(R.id.linear_layout)
|
||||
ll.setOnClickListener {
|
||||
close()
|
||||
}
|
||||
ll.setViewTreeLifecycleOwner(mView.findViewTreeLifecycleOwner())
|
||||
mWindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
}
|
||||
|
||||
@@ -62,17 +69,81 @@ class Window @SuppressLint("InflateParams") constructor(
|
||||
mWindowManager.addView(mView, mParams)
|
||||
mView.findViewById<TextView>(R.id.name).text = name
|
||||
val vid = mView.findViewById<VideoView>(R.id.video)
|
||||
|
||||
vid.setVideoPath("android.resource://me.kavishdevar.aln/" + R.raw.connected)
|
||||
vid.resolveAdjustedSize(vid.width, vid.height)
|
||||
vid.start()
|
||||
vid.setOnCompletionListener {
|
||||
vid.start()
|
||||
}
|
||||
|
||||
// receive battery broadcast and set to R.id.battery
|
||||
val batteryText = mView.findViewById<TextView>(R.id.battery)
|
||||
val batteryList = batteryNotification.getBattery()
|
||||
batteryText.text = "Why are the battery levels zero :( " + batteryList[0].level.toString() + "%" + " " + batteryList[0].status + " " + batteryList[1].level.toString() + "%" + " " + batteryList[1].status + " " + batteryList[2].level.toString() + "%" + " " + batteryList[2].status
|
||||
|
||||
val batteryStatus = batteryNotification.getBattery()
|
||||
val batteryLeftText = mView.findViewById<TextView>(R.id.left_battery)
|
||||
val batteryRightText = mView.findViewById<TextView>(R.id.right_battery)
|
||||
val batteryCaseText = mView.findViewById<TextView>(R.id.case_battery)
|
||||
|
||||
batteryLeftText.text = batteryStatus.find { it.component == BatteryComponent.LEFT }?.let {
|
||||
"\uDBC3\uDC8E ${it.level}%"
|
||||
} ?: ""
|
||||
batteryRightText.text = batteryStatus.find { it.component == BatteryComponent.RIGHT }?.let {
|
||||
"\uDBC3\uDC8D ${it.level}%"
|
||||
} ?: ""
|
||||
batteryCaseText.text = batteryStatus.find { it.component == BatteryComponent.CASE }?.let {
|
||||
"\uDBC3\uDE6C ${it.level}%"
|
||||
} ?: ""
|
||||
// bText.text =
|
||||
// batteryStatus.joinToString(separator = "") {
|
||||
// when (it.component) {
|
||||
// BatteryComponent.LEFT -> "\uDBC6\uDCE5 ${it.level}%"
|
||||
// BatteryComponent.RIGHT -> "\uDBC6\uDCE8 ${it.level}%"
|
||||
// BatteryComponent.CASE -> "\uDBC6\uDCE6 ${it.level}%"
|
||||
// else -> ""
|
||||
// }
|
||||
// }
|
||||
|
||||
// composeView.setContent {
|
||||
// Row (
|
||||
// modifier = Modifier
|
||||
// .fillMaxWidth(),
|
||||
// horizontalArrangement = Arrangement.Center,
|
||||
// verticalAlignment = Alignment.CenterVertically
|
||||
// ) {
|
||||
// Row (
|
||||
// modifier = Modifier
|
||||
// .fillMaxWidth(0.5f),
|
||||
// horizontalArrangement = Arrangement.SpaceBetween
|
||||
// ){
|
||||
// val left = batteryStatus.find { it.component == BatteryComponent.LEFT }
|
||||
// val right = batteryStatus.find { it.component == BatteryComponent.RIGHT }
|
||||
// if ((right?.status == BatteryStatus.CHARGING && left?.status == BatteryStatus.CHARGING) || (left?.status == BatteryStatus.NOT_CHARGING && right?.status == BatteryStatus.NOT_CHARGING))
|
||||
// {
|
||||
// BatteryIndicator(right.level.let { left.level.coerceAtMost(it) }, left.status == BatteryStatus.CHARGING)
|
||||
// }
|
||||
// else {
|
||||
// Row {
|
||||
// if (left?.status != BatteryStatus.DISCONNECTED) {
|
||||
// Text(text = "\uDBC6\uDCE5", fontFamily = FontFamily(Font(R.font.sf_pro)))
|
||||
// BatteryIndicator(left?.level ?: 0, left?.status == BatteryStatus.CHARGING)
|
||||
// Spacer(modifier = Modifier.width(16.dp))
|
||||
// }
|
||||
// if (right?.status != BatteryStatus.DISCONNECTED) {
|
||||
// Text(text = "\uDBC6\uDCE8", fontFamily = FontFamily(Font(R.font.sf_pro)))
|
||||
// BatteryIndicator(right?.level ?: 0, right?.status == BatteryStatus.CHARGING)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Row (
|
||||
// modifier = Modifier
|
||||
// .fillMaxWidth(),
|
||||
// horizontalArrangement = Arrangement.Center
|
||||
// ) {
|
||||
// val case =
|
||||
// batteryStatus.find { it.component == BatteryComponent.CASE }
|
||||
// BatteryIndicator(case?.level ?: 0)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Slide-up animation
|
||||
val displayMetrics = mView.context.resources.displayMetrics
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16.dp"
|
||||
android:id="@+id/linear_layout"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/shape">
|
||||
|
||||
@@ -12,6 +13,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:id="@+id/constraint_layout"
|
||||
android:paddingBottom="48dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
@@ -49,15 +51,59 @@
|
||||
android:contentDescription="AirPods"
|
||||
android:src="@raw/connected"
|
||||
tools:ignore="HardcodedText" />
|
||||
<TextView
|
||||
android:id="@+id/battery"
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/sf_pro"
|
||||
android:gravity="center"
|
||||
android:text=""
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- Left Half -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:textAlignment="center"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/sf_pro"
|
||||
android:text=""
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:id="@+id/left_battery"
|
||||
android:gravity="center"
|
||||
tools:ignore="NestedWeights" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:textAlignment="center"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/sf_pro"
|
||||
android:gravity="center"
|
||||
android:text=""
|
||||
android:id="@+id/right_battery"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Right Half -->
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:textAlignment="center"
|
||||
android:id="@+id/case_battery"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/sf_pro"
|
||||
android:gravity="center"
|
||||
android:text=""
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user