idk what i'm doing

This commit is contained in:
Kavish Devar
2024-12-01 22:25:18 +05:30
parent 4a1d7df82d
commit 71dffd1415
6 changed files with 181 additions and 39 deletions

View File

@@ -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)

View File

@@ -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,
)
},

View File

@@ -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")
}
}
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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>