feat: statusBar ui

This commit is contained in:
yangxisong 2025-11-14 11:44:49 +08:00
parent 189ffa71bf
commit 6b234f86e7
16 changed files with 253 additions and 3 deletions

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" />

View File

@ -6,9 +6,12 @@ import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.yuanxuan.rokid.databinding.ActivityMainBinding import com.yuanxuan.rokid.databinding.ActivityMainBinding
import com.yuanxuan.rokid.dependencies.AppDependencies import com.yuanxuan.rokid.dependencies.AppDependencies
import com.yuanxuan.rokid.device.DeviceServiceManager
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@ -34,6 +37,19 @@ class MainActivity : AppCompatActivity() {
*/ */
AppDependencies.deviceServiceManager.batteryPercentage.collect { AppDependencies.deviceServiceManager.batteryPercentage.collect {
binding.batteryLevel.text = "${it}%" binding.batteryLevel.text = "${it}%"
binding.batteryLevelIv.setImageLevel(it)
}
}
lifecycleScope.launch {
AppDependencies.deviceServiceManager.wifiState.collect {
when (it) {
is DeviceServiceManager.WifiState.Connected -> {
binding.wifiIv.setImageLevel(it.level)
binding.wifiIv.isVisible = true
}
DeviceServiceManager.WifiState.Unconnected -> binding.wifiIv.isGone = true
}
} }
} }

View File

@ -5,6 +5,11 @@ 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.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.WifiManager
import android.os.BatteryManager import android.os.BatteryManager
import com.rokid.dcg.sprite.service.IInstructListener import com.rokid.dcg.sprite.service.IInstructListener
import com.rokid.dcg.sprite.service.IInstructService import com.rokid.dcg.sprite.service.IInstructService
@ -29,7 +34,7 @@ import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException import kotlin.coroutines.resumeWithException
class DeviceServiceManager(val context: Application) { class DeviceServiceManager(val context: Application) : ConnectivityManager.NetworkCallback() {
companion object { companion object {
/** /**
@ -52,6 +57,15 @@ class DeviceServiceManager(val context: Application) {
private val _batteryPercentage = MutableStateFlow(-1) private val _batteryPercentage = MutableStateFlow(-1)
val batteryPercentage = _batteryPercentage.asStateFlow() val batteryPercentage = _batteryPercentage.asStateFlow()
/**
* wifi
*/
private val _wifiState: MutableStateFlow<WifiState> = MutableStateFlow(WifiState.Unconnected)
val wifiState = _wifiState.asStateFlow()
private val wifiManager by lazy {
context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
}
lateinit var sn: String lateinit var sn: String
private set private set
@ -86,6 +100,16 @@ class DeviceServiceManager(val context: Application) {
} }
} }
} }
/**
* 监听wifi状态
*/
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build()
connectivityManager.registerNetworkCallback(request, this)
} }
val instructListener = object : IInstructListener.Stub() { val instructListener = object : IInstructListener.Stub() {
@ -274,10 +298,29 @@ class DeviceServiceManager(val context: Application) {
} }
} }
override fun onLost(network: Network) {
_wifiState.update { WifiState.Unconnected }
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
_wifiState.update {
val level = wifiManager.calculateSignalLevel(networkCapabilities.signalStrength)
WifiState.Connected(
// maxSignalLevel是4 level区间应该是 0-3 这里却返回了4 限制一下
level = level.coerceAtMost(wifiManager.maxSignalLevel - 1)
)
}
}
sealed interface InstructState { sealed interface InstructState {
data object None : InstructState data object None : InstructState
data object WaitingInstructState : InstructState data object WaitingInstructState : InstructState
} }
sealed interface WifiState {
data object Unconnected : WifiState
data class Connected(val level: Int) : WifiState
}
} }

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/icon_battery_0"
android:minLevel="0"
android:maxLevel="12" />
<item
android:drawable="@drawable/icon_battery_25"
android:minLevel="13"
android:maxLevel="49" />
<item
android:drawable="@drawable/icon_battery_50"
android:minLevel="50"
android:maxLevel="74" />
<item
android:drawable="@drawable/icon_battery_75"
android:minLevel="75"
android:maxLevel="90" />
<item
android:drawable="@drawable/icon_battery_100"
android:minLevel="91"
android:maxLevel="100" />
</level-list>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,6L20,6A2,2 0,0 1,22 8L22,16A2,2 0,0 1,20 18L4,18A2,2 0,0 1,2 16L2,8A2,2 0,0 1,4 6z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
</vector>

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,6L20,6A2,2 0,0 1,22 8L22,16A2,2 0,0 1,20 18L4,18A2,2 0,0 1,2 16L2,8A2,2 0,0 1,4 6z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
<path
android:pathData="M5,8L19,8A1,1 0,0 1,20 9L20,15A1,1 0,0 1,19 16L5,16A1,1 0,0 1,4 15L4,9A1,1 0,0 1,5 8z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,6L20,6A2,2 0,0 1,22 8L22,16A2,2 0,0 1,20 18L4,18A2,2 0,0 1,2 16L2,8A2,2 0,0 1,4 6z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
<path
android:pathData="M5,8L7,8A1,1 0,0 1,8 9L8,15A1,1 0,0 1,7 16L5,16A1,1 0,0 1,4 15L4,9A1,1 0,0 1,5 8z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,6L20,6A2,2 0,0 1,22 8L22,16A2,2 0,0 1,20 18L4,18A2,2 0,0 1,2 16L2,8A2,2 0,0 1,4 6z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
<path
android:pathData="M5,8L11,8A1,1 0,0 1,12 9L12,15A1,1 0,0 1,11 16L5,16A1,1 0,0 1,4 15L4,9A1,1 0,0 1,5 8z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,6L20,6A2,2 0,0 1,22 8L22,16A2,2 0,0 1,20 18L4,18A2,2 0,0 1,2 16L2,8A2,2 0,0 1,4 6z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
<path
android:pathData="M5,8L15,8A1,1 0,0 1,16 9L16,15A1,1 0,0 1,15 16L5,16A1,1 0,0 1,4 15L4,9A1,1 0,0 1,5 8z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.633,20.35C12.338,20.35 12.91,19.779 12.91,19.074C12.91,18.368 12.338,17.797 11.633,17.797C10.928,17.797 10.356,18.368 10.356,19.074C10.356,19.779 10.928,20.35 11.633,20.35Z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.633,20.35C12.338,20.35 12.91,19.779 12.91,19.074C12.91,18.368 12.338,17.797 11.633,17.797C10.928,17.797 10.356,18.368 10.356,19.074C10.356,19.779 10.928,20.35 11.633,20.35Z"
android:fillColor="#000000"/>
<path
android:pathData="M11.633,13.395C13.209,13.395 14.686,13.751 15.959,14.372L16.211,14.5L16.324,14.569C16.855,14.946 16.888,15.75 16.344,16.156L16.317,16.176H16.31C16.048,16.355 15.722,16.395 15.429,16.291L15.301,16.235C14.25,15.686 12.989,15.361 11.633,15.361C10.386,15.361 9.215,15.634 8.219,16.108C7.881,16.269 7.483,16.229 7.188,15.992H7.181L7.152,15.969C6.613,15.508 6.73,14.648 7.367,14.342L7.848,14.129C8.99,13.66 10.275,13.395 11.633,13.395Z"
android:strokeWidth="0.2"
android:fillColor="#000000"
android:strokeColor="#000000"/>
</vector>

View File

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.633,20.35C12.338,20.35 12.91,19.779 12.91,19.074C12.91,18.368 12.338,17.797 11.633,17.797C10.928,17.797 10.356,18.368 10.356,19.074C10.356,19.779 10.928,20.35 11.633,20.35Z"
android:fillColor="#000000"/>
<path
android:pathData="M11.633,13.395C13.209,13.395 14.686,13.751 15.959,14.372L16.211,14.5L16.324,14.569C16.855,14.946 16.887,15.75 16.344,16.156L16.317,16.176H16.31C16.048,16.355 15.722,16.395 15.429,16.291L15.301,16.235C14.25,15.686 12.989,15.361 11.633,15.361C10.386,15.361 9.215,15.634 8.219,16.108C7.881,16.269 7.483,16.229 7.188,15.992H7.181L7.152,15.969C6.613,15.508 6.73,14.648 7.367,14.342L7.848,14.129C8.99,13.66 10.275,13.395 11.633,13.395Z"
android:strokeWidth="0.2"
android:fillColor="#000000"
android:strokeColor="#000000"/>
<path
android:pathData="M11.633,8.646C14.609,8.646 17.357,9.487 19.544,10.894C20.117,11.263 20.14,12.095 19.595,12.501C19.271,12.743 18.833,12.759 18.492,12.541C16.641,11.349 14.29,10.628 11.733,10.61V10.612H11.633C9.252,10.612 7.047,11.221 5.25,12.253H5.249C4.891,12.458 4.443,12.413 4.13,12.144C3.619,11.708 3.69,10.892 4.274,10.557C6.363,9.354 8.9,8.646 11.633,8.646Z"
android:strokeWidth="0.2"
android:fillColor="#000000"
android:strokeColor="#000000"/>
</vector>

View File

@ -0,0 +1,24 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.633,20.35C12.338,20.35 12.91,19.779 12.91,19.074C12.91,18.368 12.338,17.797 11.633,17.797C10.928,17.797 10.356,18.368 10.356,19.074C10.356,19.779 10.928,20.35 11.633,20.35Z"
android:fillColor="#000000"/>
<path
android:pathData="M11.633,13.395C13.209,13.395 14.686,13.751 15.959,14.372L16.211,14.5L16.324,14.569C16.855,14.946 16.887,15.75 16.344,16.156L16.317,16.176H16.31C16.048,16.355 15.722,16.395 15.429,16.291L15.301,16.235C14.25,15.686 12.989,15.361 11.633,15.361C10.386,15.361 9.215,15.634 8.219,16.108C7.881,16.269 7.483,16.229 7.188,15.992H7.181L7.152,15.969C6.613,15.508 6.73,14.648 7.367,14.342L7.848,14.129C8.99,13.66 10.275,13.395 11.633,13.395Z"
android:strokeWidth="0.2"
android:fillColor="#000000"
android:strokeColor="#000000"/>
<path
android:pathData="M11.633,8.646C14.609,8.646 17.357,9.487 19.544,10.894C20.117,11.263 20.14,12.095 19.595,12.501C19.271,12.743 18.833,12.759 18.492,12.541C16.641,11.349 14.29,10.628 11.733,10.61V10.612H11.633C9.252,10.612 7.047,11.221 5.25,12.253H5.249C4.891,12.458 4.443,12.413 4.13,12.144C3.619,11.708 3.69,10.892 4.274,10.557C6.363,9.354 8.9,8.646 11.633,8.646Z"
android:strokeWidth="0.2"
android:fillColor="#000000"
android:strokeColor="#000000"/>
<path
android:pathData="M11.633,3.9C15.844,3.9 19.704,5.162 22.683,7.253L22.778,7.329C23.228,7.734 23.208,8.464 22.707,8.841L22.68,8.861H22.672C22.341,9.089 21.901,9.094 21.569,8.861C18.911,7 15.435,5.866 11.634,5.866C8.368,5.867 5.344,6.702 2.871,8.117L2.384,8.408C2.069,8.603 1.674,8.596 1.366,8.406L1.24,8.313C0.735,7.88 0.805,7.086 1.369,6.735C4.23,4.956 7.784,3.9 11.633,3.9Z"
android:strokeWidth="0.2"
android:fillColor="#000000"
android:strokeColor="#000000"/>
</vector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/icon_wifi_1"
android:maxLevel="0" />
<item
android:drawable="@drawable/icon_wifi_2"
android:maxLevel="1" />
<item
android:drawable="@drawable/icon_wifi_3"
android:maxLevel="2" />
<item
android:drawable="@drawable/icon_wifi_4"
android:maxLevel="3" />
</level-list>

View File

@ -18,9 +18,23 @@
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<ImageView <ImageView
android:id="@+id/wifi_iv"
android:layout_width="@dimen/status_bar_icon_size" android:layout_width="@dimen/status_bar_icon_size"
android:layout_height="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size"
android:src="@mipmap/ic_launcher" android:layout_marginEnd="5.dp"
android:src="@drawable/wifi_level_list"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="@id/battery_level"
app:layout_constraintEnd_toStartOf="@id/battery_level_iv"
app:layout_constraintTop_toTopOf="@id/battery_level" />
<ImageView
android:id="@+id/battery_level_iv"
android:layout_width="@dimen/status_bar_icon_size"
android:layout_height="@dimen/status_bar_icon_size"
android:layout_marginEnd="5.dp"
android:src="@drawable/battery_level_list"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="@id/battery_level" app:layout_constraintBottom_toBottomOf="@id/battery_level"
app:layout_constraintEnd_toStartOf="@id/battery_level" app:layout_constraintEnd_toStartOf="@id/battery_level"
app:layout_constraintTop_toTopOf="@id/battery_level" /> app:layout_constraintTop_toTopOf="@id/battery_level" />

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<dimen name="status_bar_text_size">12.sp</dimen> <dimen name="status_bar_text_size">12.sp</dimen>
<dimen name="status_bar_icon_size">12.dp</dimen> <dimen name="status_bar_icon_size">16.dp</dimen>
</resources> </resources>