mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-03-14 02:02:30 +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 androidx.core.app.NotificationCompat
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
||||||
|
|
||||||
@@ -35,8 +36,8 @@ class AirPodsService: Service() {
|
|||||||
return LocalBinder()
|
return LocalBinder()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showPopup(context: Context, name: String) {
|
fun showPopup(service: Service, name: String) {
|
||||||
val window = Window(context)
|
val window = Window(service.applicationContext)
|
||||||
window.open(name, batteryNotification)
|
window.open(name, batteryNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ class AirPodsService: Service() {
|
|||||||
intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE", BluetoothDevice::class.java)
|
intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE", BluetoothDevice::class.java)
|
||||||
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)
|
||||||
if (bluetoothDevice != null && action != null && !action.isEmpty()) {
|
if (bluetoothDevice != null && action != null && !action.isEmpty()) {
|
||||||
Log.d("BluetoothReceiver", "Received broadcast")
|
Log.d("BluetoothReceiver", "Received broadcast")
|
||||||
if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
|
if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
|
||||||
@@ -54,7 +56,7 @@ class AirPodsService: Service() {
|
|||||||
if (bluetoothDevice.uuids.contains(uuid)) {
|
if (bluetoothDevice.uuids.contains(uuid)) {
|
||||||
Log.d("AirPodsService", "Service started")
|
Log.d("AirPodsService", "Service started")
|
||||||
val intent = Intent(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
|
val intent = Intent(AirPodsNotifications.AIRPODS_CONNECTION_DETECTED)
|
||||||
intent.putExtra("name", bluetoothDevice.name)
|
intent.putExtra("name", name)
|
||||||
intent.putExtra("device", bluetoothDevice)
|
intent.putExtra("device", bluetoothDevice)
|
||||||
context?.sendBroadcast(intent)
|
context?.sendBroadcast(intent)
|
||||||
}
|
}
|
||||||
@@ -104,8 +106,9 @@ class AirPodsService: Service() {
|
|||||||
|
|
||||||
registerReceiver(object: BroadcastReceiver() {
|
registerReceiver(object: BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
showPopup(context!!, intent!!.getStringExtra("name")!!)
|
val name = this@AirPodsService.getSharedPreferences("settings", MODE_PRIVATE).getString("name", device?.name)
|
||||||
device = intent.getParcelableExtra("device", BluetoothDevice::class.java)!!
|
device = intent?.getParcelableExtra("device", BluetoothDevice::class.java)!!
|
||||||
|
showPopup(this@AirPodsService, name.toString())
|
||||||
connectToSocket(device!!)
|
connectToSocket(device!!)
|
||||||
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_CONNECTED).apply {
|
sendBroadcast(Intent(AirPodsNotifications.AIRPODS_CONNECTED).apply {
|
||||||
putExtra("device", device)
|
putExtra("device", device)
|
||||||
@@ -188,12 +191,18 @@ class AirPodsService: Service() {
|
|||||||
this@AirPodsService.device = device
|
this@AirPodsService.device = device
|
||||||
isConnected = true
|
isConnected = true
|
||||||
socket.let { it ->
|
socket.let { it ->
|
||||||
it.outputStream.write(Enums.HANDSHAKE.value)
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
it.outputStream.flush()
|
it.outputStream.write(Enums.HANDSHAKE.value)
|
||||||
it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value)
|
it.outputStream.flush()
|
||||||
it.outputStream.flush()
|
delay(500)
|
||||||
it.outputStream.write(Enums.REQUEST_NOTIFICATIONS.value)
|
it.outputStream.write(Enums.SET_SPECIFIC_FEATURES.value)
|
||||||
it.outputStream.flush()
|
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(
|
sendBroadcast(
|
||||||
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
Intent(AirPodsNotifications.AIRPODS_CONNECTED)
|
||||||
.putExtra("device", device)
|
.putExtra("device", device)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
|||||||
import android.bluetooth.BluetoothDevice
|
import android.bluetooth.BluetoothDevice
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Context.MODE_PRIVATE
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
@@ -82,6 +83,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.primex.core.ExperimentalToolkitApi
|
import com.primex.core.ExperimentalToolkitApi
|
||||||
import com.primex.core.blur.newBackgroundBlur
|
import com.primex.core.blur.newBackgroundBlur
|
||||||
|
import me.kavishdevar.aln.AirPodsService
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -90,7 +92,12 @@ fun BatteryView() {
|
|||||||
@Suppress("DEPRECATION") val batteryReceiver = remember {
|
@Suppress("DEPRECATION") val batteryReceiver = remember {
|
||||||
object : BroadcastReceiver() {
|
object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
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) {
|
LaunchedEffect(context) {
|
||||||
val batteryIntentFilter = IntentFilter(AirPodsNotifications.BATTERY_DATA)
|
val batteryIntentFilter = IntentFilter(AirPodsNotifications.BATTERY_DATA)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
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(
|
CenterAlignedTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text(
|
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,
|
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;")
|
HiddenApiBypass.addHiddenApiExemptions("Landroid/bluetooth/BluetoothSocket;")
|
||||||
val manager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
|
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("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 socket = device.createInsecureL2capChannel(31)
|
||||||
|
|
||||||
|
val batteryLevel = remember { mutableStateOf("") }
|
||||||
// socket.outputStream.write(byteArrayOf(0x12,0x3B,0x00,0x02, 0x00))
|
// socket.outputStream.write(byteArrayOf(0x12,0x3B,0x00,0x02, 0x00))
|
||||||
// socket.outputStream.write(byteArrayOf(0x12, 0x3A, 0x00, 0x01, 0x00, 0x08,0x01))
|
// socket.outputStream.write(byteArrayOf(0x12, 0x3A, 0x00, 0x01, 0x00, 0x08,0x01))
|
||||||
|
|
||||||
@@ -66,9 +67,12 @@ class CustomDevice : ComponentActivity() {
|
|||||||
gatt.services.forEach { service ->
|
gatt.services.forEach { service ->
|
||||||
Log.d("GATT", "Service UUID: ${service.uuid}")
|
Log.d("GATT", "Service UUID: ${service.uuid}")
|
||||||
service.characteristics.forEach { characteristic ->
|
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 = {
|
Button(onClick = {
|
||||||
val characteristicUuid = "4f860002-943b-49ef-bed4-2f730304427a"
|
// val characteristicUuid = "4f860002-943b-49ef-bed4-2f730304427a"
|
||||||
val value = byteArrayOf(0x01, 0x00, 0x02)
|
// 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.registerReceiver(disconnectReceiver, IntentFilter(AirPodsNotifications.AIRPODS_DISCONNECTED),
|
||||||
Context.RECEIVER_NOT_EXPORTED)
|
Context.RECEIVER_NOT_EXPORTED)
|
||||||
|
|
||||||
|
|
||||||
// UI logic
|
// UI logic
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
@@ -127,7 +126,8 @@ fun Main() {
|
|||||||
|
|
||||||
context.bindService(Intent(context, AirPodsService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
|
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")
|
Log.d("ALN", "Connected")
|
||||||
navController.navigate("settings")
|
navController.navigate("settings")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -14,17 +14,19 @@ import android.view.WindowManager
|
|||||||
import android.view.animation.AccelerateInterpolator
|
import android.view.animation.AccelerateInterpolator
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.VideoView
|
import android.widget.VideoView
|
||||||
|
import androidx.lifecycle.findViewTreeLifecycleOwner
|
||||||
|
import androidx.lifecycle.setViewTreeLifecycleOwner
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
class Window @SuppressLint("InflateParams") constructor(
|
@SuppressLint("InflateParams")
|
||||||
context: Context
|
class Window (context: Context) {
|
||||||
) {
|
|
||||||
private val mView: View
|
private val mView: View
|
||||||
private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams(
|
private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams(
|
||||||
(context.resources.displayMetrics.widthPixels * 0.95).toInt(),
|
(context.resources.displayMetrics.widthPixels * 0.95).toInt(),
|
||||||
@@ -50,6 +52,11 @@ class Window @SuppressLint("InflateParams") constructor(
|
|||||||
close()
|
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
|
mWindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,17 +69,81 @@ class Window @SuppressLint("InflateParams") constructor(
|
|||||||
mWindowManager.addView(mView, mParams)
|
mWindowManager.addView(mView, mParams)
|
||||||
mView.findViewById<TextView>(R.id.name).text = name
|
mView.findViewById<TextView>(R.id.name).text = name
|
||||||
val vid = mView.findViewById<VideoView>(R.id.video)
|
val vid = mView.findViewById<VideoView>(R.id.video)
|
||||||
|
|
||||||
vid.setVideoPath("android.resource://me.kavishdevar.aln/" + R.raw.connected)
|
vid.setVideoPath("android.resource://me.kavishdevar.aln/" + R.raw.connected)
|
||||||
vid.resolveAdjustedSize(vid.width, vid.height)
|
vid.resolveAdjustedSize(vid.width, vid.height)
|
||||||
vid.start()
|
vid.start()
|
||||||
vid.setOnCompletionListener {
|
vid.setOnCompletionListener {
|
||||||
vid.start()
|
vid.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
// receive battery broadcast and set to R.id.battery
|
val batteryStatus = batteryNotification.getBattery()
|
||||||
val batteryText = mView.findViewById<TextView>(R.id.battery)
|
val batteryLeftText = mView.findViewById<TextView>(R.id.left_battery)
|
||||||
val batteryList = batteryNotification.getBattery()
|
val batteryRightText = mView.findViewById<TextView>(R.id.right_battery)
|
||||||
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 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
|
// Slide-up animation
|
||||||
val displayMetrics = mView.context.resources.displayMetrics
|
val displayMetrics = mView.context.resources.displayMetrics
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="16.dp"
|
android:layout_margin="16.dp"
|
||||||
|
android:id="@+id/linear_layout"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:background="@drawable/shape">
|
android:background="@drawable/shape">
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
|
android:id="@+id/constraint_layout"
|
||||||
android:paddingBottom="48dp"
|
android:paddingBottom="48dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
@@ -49,15 +51,59 @@
|
|||||||
android:contentDescription="AirPods"
|
android:contentDescription="AirPods"
|
||||||
android:src="@raw/connected"
|
android:src="@raw/connected"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
<TextView
|
|
||||||
android:id="@+id/battery"
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:orientation="horizontal">
|
||||||
android:fontFamily="@font/sf_pro"
|
|
||||||
android:gravity="center"
|
<!-- Left Half -->
|
||||||
android:text=""
|
<LinearLayout
|
||||||
android:textColor="@color/white"
|
android:layout_width="0dp"
|
||||||
android:textSize="16sp"
|
android:layout_height="wrap_content"
|
||||||
tools:ignore="HardcodedText" />
|
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>
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user