修改hareware,新增dashboard

This commit is contained in:
yuqian 2026-01-17 18:28:40 +08:00
parent 689b92bfd0
commit fee044b500
23 changed files with 707 additions and 360 deletions

View File

@ -39,4 +39,13 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
}
protected open fun initData() {}
override fun onResume() {
super.onResume()
mainViewModel.startRealTimeRefresh(this)
}
override fun onPause() {
super.onPause()
mainViewModel.stopRealTimeRefresh()
}
}

View File

@ -5,11 +5,18 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import com.xyzshell.andinfo.AndInfo
import com.xyzshell.myphoneinfo.R
import com.xyzshell.myphoneinfo.custom.RefreshManager.load
import com.xyzshell.myphoneinfo.custom.RefreshManager.stop
import com.xyzshell.myphoneinfo.custom.SetNumberOrWordUtils.setDecimal1
import com.xyzshell.myphoneinfo.databinding.FragmentBatteryBinding
import com.xyzshell.myphoneinfo.main.MainViewModel
class BatteryFragment : Fragment() {
private lateinit var binding: FragmentBatteryBinding
private val mainViewModel: MainViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
@ -21,11 +28,67 @@ class BatteryFragment : Fragment() {
// Inflate the layout for this fragment
binding = FragmentBatteryBinding.inflate(inflater, container, false)
initView()
binding.swipeRefresh.setOnRefreshListener {
load(binding.swipeRefresh)
mainViewModel.refreshBatteryInfo()
}
return binding.root
}
private fun initView() {
override fun onResume() {
super.onResume()
mainViewModel.refreshBatteryInfo()
}
private fun initView() {
binding.info1.textTitle.text=getString(R.string.temperature)
binding.info2.textTitle.text=getString(R.string.technology)
binding.info3.textTitle.text=getString(R.string.health)
binding.info4.textTitle.text=getString(R.string.capacity_by)
binding.info5.textTitle.text=getString(R.string.charge_count)
binding.info6.textTitle.text=getString(R.string.charging_cycle)
mainViewModel.batteryInfo.observe(viewLifecycleOwner){batteryInfo ->
batteryInfo?.let {
stop(binding.swipeRefresh)
it.getBatteryDetails().let {item->
val percentage = item.percentage
binding.signalStrength.text = "$percentage%"
binding.textCurrent.visibility= View.VISIBLE
binding.textPower.visibility= View.VISIBLE
binding.textRemain.visibility= View.VISIBLE
if(item.isCharging){
if(percentage == 100){
binding.conText1.text = getString(R.string.full_usb)+" ${item.plugType}"
}else{
binding.conText1.text= getString(R.string.charging_usb)+" ${item.plugType}"
}
binding.conTExt3.text=" ${item.currentNow} mA"
binding.conTExt4.text=" ${setDecimal1(item.powerUsage ?: 0.00)} W"
binding.conTExt5.text=" ${item.voltage} mV"
}else{
binding.conText1.text= getString(R.string.discharging)
binding.textCurrent.visibility= View.GONE
binding.textPower.visibility= View.GONE
binding.textRemain.visibility= View.GONE
}
binding.info1.textContent.text=item.temperature.toString()+"°C"
//电池类型
// binding.info2.textTitle.text=item.
binding.info3.textContent.text=item.health
binding.info4.textContent.text="${item.capacity} mAh"
binding.info5.textContent.text="${item.chargeCounter} mAh"
binding.info6.textContent.text="${item.chargeCycles}"
}
}
}
}
companion object {

View File

@ -1,16 +1,15 @@
package com.xyzshell.myphoneinfo.dashboard
import android.Manifest
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresPermission
import androidx.core.app.ActivityCompat
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.xyzshell.andinfo.AndInfo
import com.xyzshell.andinfo.libs.BatteryDetails
import com.xyzshell.andinfo.libs.BuildInfo
import com.xyzshell.myphoneinfo.R
import com.xyzshell.myphoneinfo.base.BaseFragment
import com.xyzshell.myphoneinfo.databinding.FragmentDashboardBinding
import com.xyzshell.myphoneinfo.dialog.DialogAppInstall
@ -20,6 +19,7 @@ import com.xyzshell.myphoneinfo.dialog.DialogMemory
import com.xyzshell.myphoneinfo.dialog.DialogNetwork
import com.xyzshell.myphoneinfo.dialog.DialogOperating
import com.xyzshell.myphoneinfo.dialog.DialogStorage
import com.xyzshell.myphoneinfo.main.MainViewModel
private const val ARG_PARAM1 = "param1"
@ -37,6 +37,9 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>() {
private var dialogAppInstall: DialogAppInstall? = null
private var dialogMemory: DialogMemory? = null
private var dialogStorage: DialogStorage? = null
private val mainViewModel: MainViewModel by activityViewModels()
private lateinit var buildDialogInfo: BuildInfo
private lateinit var batteryDialogInfo: BatteryDetails
companion object {
@ -68,11 +71,48 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setObserve()
initCpu()
initClick()
}
private fun setObserve(){
//top
mainViewModel.deviceInfo.observe(viewLifecycleOwner) {deviceInfo ->
binding.layoutTop.phoneLogo.text=deviceInfo?.brand
binding.layoutTop.tvPhoneBrand.text=deviceInfo?.brand
}
mainViewModel.cpuInfo.observe(viewLifecycleOwner) {cpuInfo ->
binding.layoutTop.tvPhoneApiVersion.text=cpuInfo?.getProcessorName()
}
mainViewModel.buildInfo.observe(viewLifecycleOwner) {buildInfo ->
if (buildInfo != null) {
buildDialogInfo=buildInfo
}
binding.layoutTop.tvAndroidVersion.text="Android ${buildInfo?.versionRelease} (${buildInfo?.versionCodename})"
}
//center
mainViewModel.batteryInfo.observe(viewLifecycleOwner) {batteryInfo ->
batteryInfo?.getBatteryDetails().let{
if (it != null) {
batteryDialogInfo=it
}
when(it?.percentage){
in 0..25->binding.layoutCenter.iconBattery.setImageResource(R.mipmap.property_125)
in 25..50->binding.layoutCenter.iconBattery.setImageResource(R.mipmap.property_150)
in 50..75->binding.layoutCenter.iconBattery.setImageResource(R.mipmap.property_175)
in 75..100->binding.layoutCenter.iconBattery.setImageResource(R.mipmap.property_1full)
else->binding.layoutCenter.iconBattery.setImageResource(R.mipmap.property_1full)
}
binding.layoutCenter.seekbar.progress=it!!.percentage
binding.layoutCenter.percent.text=it.percentage.toString()+"%"
binding.layoutCenter.batteryContent.text="${it.temperature}°C"
}
}
}
private fun initCpu() {
binding.layoutCpu.run {
@ -107,7 +147,7 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>() {
}
binding.layoutCenter.run {
relayoutBattery.setOnClickListener {
dialogBattery = dialogBattery ?: DialogBattery()
dialogBattery = dialogBattery ?: DialogBattery(batteryDialogInfo)
dialogBattery?.show(parentFragmentManager, "")
}
relayoutNetwork.setOnClickListener {
@ -132,7 +172,7 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>() {
}
}
binding.layoutTop.root.setOnClickListener {
dialogOperating = dialogOperating ?: DialogOperating()
dialogOperating = dialogOperating ?: DialogOperating(buildDialogInfo)
dialogOperating?.show(parentFragmentManager, "")
}
binding.layoutBottom.run {

View File

@ -36,8 +36,8 @@ import kotlin.math.roundToInt
class HardWareFragment : Fragment() {
private lateinit var binding: FragmentHardWareBinding
private var dialogBlueTooth: DialogBlueTooth? = null
private var dialogNearBlueTooth: DialogBlueTooth? = null
// private var dialogBlueTooth: DialogBlueTooth? = null
// private var dialogNearBlueTooth: DialogBlueTooth? = null
private var dialogInput: DialogInput? = null
private var dialogExtension: DialogExtension? = null
private var dialogDiskPart: DialogDiskPart? = null
@ -94,7 +94,6 @@ class HardWareFragment : Fragment() {
load(binding.swipeRefresh)
mainViewModel.refreshHardwareInfo(requireContext())
}
return binding.root
}
@ -208,10 +207,14 @@ class HardWareFragment : Fragment() {
binding.memoryLayout.radius1.text = appsAndData
binding.memoryLayout.radius2.text = system
binding.memoryLayout.radius3.text = other
binding.memoryLayout.seekbar3.progress =
(stoUsed.substringBefore(" ").toDouble() / stoTotal.substringBefore(" ")
.toDouble() * 100).toInt()
//appsAndData
binding.memoryLayout.seekbarr2.progress =
// (breakdown.appsAndDataSize.toDouble() / breakdown.totalSpace.toDouble() * 100).toInt()
50
//system
binding.memoryLayout.seekbarr1.progress =
// ((50+storageInfo.systemSize).toDouble() / breakdown.totalSpace.toDouble() * 100).toInt()
70
//internalStorage
val interUsed = storageInfo.getInternalStorageBreakdown().usedSpace
@ -509,7 +512,7 @@ class HardWareFragment : Fragment() {
* 显示已配对设备弹窗
*/
private fun showPairedDevicesDialog() {
dialogBlueTooth = dialogBlueTooth ?: DialogBlueTooth(type = 0)
val dialogBlueTooth = DialogBlueTooth(type = 0)
println("showBluetoothDialog" + AndInfo.instance.bluetooth.bondedDevices.size)
dialogBlueTooth?.show(childFragmentManager, "BlueTooth1")
}
@ -529,7 +532,7 @@ class HardWareFragment : Fragment() {
Toast.makeText(requireContext(), "请先开启蓝牙", Toast.LENGTH_SHORT).show()
return
}
dialogNearBlueTooth = dialogNearBlueTooth ?: DialogBlueTooth(type = 1)
val dialogNearBlueTooth = DialogBlueTooth(type = 1)
println("showBluetoothDialog" + AndInfo.instance.bluetooth.bondedDevices.size)
dialogNearBlueTooth?.show(childFragmentManager, "BlueTooth2")
}

View File

@ -58,14 +58,17 @@ class NetworkFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView()
binding.swipeRefresh.setOnRefreshListener {
load(binding.swipeRefresh)
mainViewModel.refreshNetworkInfo(requireContext())
}
setObservers()
}
private fun setObservers() {
mainViewModel.networkStatus.observe(viewLifecycleOwner) { type ->
stop(binding.swipeRefresh)
Log.d("NetworkFragment", "setObservers: $type")
when (type) {
NetworkInfo.NetworkType.WIFI -> {
status = 1
@ -124,7 +127,7 @@ class NetworkFragment : Fragment() {
onDenied = {
Toast.makeText(
context,
getString(R.string.permissions_required),
getString(R.string.net_permissions_required),
Toast.LENGTH_SHORT
).show()
setNoConnect()
@ -179,13 +182,6 @@ class NetworkFragment : Fragment() {
showLoadFragment.show(requireActivity().supportFragmentManager, tag)
}
}
binding.swipeRefresh.setOnRefreshListener {
load(binding.swipeRefresh){
Log.d("TTTTTTTT","刷新超时")
}
mainViewModel.refreshNetworkInfo(requireContext())
}
}
@ -202,7 +198,6 @@ class NetworkFragment : Fragment() {
* */
private fun setMobileInfo(mobileDetails: NetworkInfo.MobileDetails) {
binding.noConnect.visibility = View.GONE
binding.conText1.text = getString(R.string.mobile)
binding.connectData.visibility = View.VISIBLE
Log.d("TTTTTTTT", "wifi not connected")
binding.networkLayout.wifiList.visibility = View.GONE
@ -257,14 +252,13 @@ class NetworkFragment : Fragment() {
* 设置wifi信息
* */
private fun setWifiDetail(wifiDetails: NetworkInfo.WifiDetails) {
binding.networkLayout.wfText1.textContent.text = if(wifiDetails.connected) getString(R.string.connected) else getString(R.string.not_connected)
if(status==1){
binding.noConnect.visibility = View.GONE
binding.conText1.text = getString(R.string.wifi)
binding.connectData.visibility = View.VISIBLE
binding.networkLayout.wifiList.visibility = View.VISIBLE
binding.networkLayout.llPubShow.visibility = View.VISIBLE
Log.d("TTTTTTTT", wifiDetails.connected.toString())
binding.networkLayout.wifiList.visibility = View.VISIBLE
binding.networkLayout.wfText1.textContent.text = getString(R.string.connected)
wifiDetails.signalLevelPercent?.let { percent ->
binding.strengthView.setStrength(calculateSignalLevel(percent = percent))
}
@ -291,7 +285,7 @@ class NetworkFragment : Fragment() {
val toString = wifiDetails.ipv6.toString()
val ipv6 = toString.replace("[", "").replace("]", "")
binding.networkLayout.dhText8.textContent.text = ipv6
}
binding.networkLayout.hardCheck1.image.isSelected =
wifiDetails.supportedStandards?.size == 5
binding.networkLayout.hardCheck2.image.isSelected = wifiDetails.wifiDirect == true
@ -299,7 +293,6 @@ class NetworkFragment : Fragment() {
binding.networkLayout.hardCheck4.image.isSelected = wifiDetails.wifiPasspoint == true
binding.networkLayout.hardCheck5.image.isSelected = wifiDetails.support5G == true
binding.networkLayout.hardCheck6.image.isSelected = wifiDetails.support6G == true
}
private fun calculateSignalLevel(percent: Int): Int {

View File

@ -102,7 +102,6 @@ private val mainViewModel: MainViewModel by activityViewModels()
binding.textOp9.textTitle.text=getString(R.string.initial_release)
// todo
binding.textOp11.textTitle.text=getString(R.string.instruction_sets)
// todo
binding.textOp10.textTitle.text=getString(R.string.architecture)
binding.textOp12.textTitle.text=getString(R.string.treble)
binding.textOp13.textTitle.text=getString(R.string.root_access)
@ -115,6 +114,7 @@ private val mainViewModel: MainViewModel by activityViewModels()
binding.textOp20.textTitle.text=getString(R.string.kernel)
mainViewModel.buildInfo.observe(viewLifecycleOwner) { buildInfo ->
buildInfo?.let {
binding.androidName.text="Android ${buildInfo.versionRelease} (${buildInfo.versionCodename})"
binding.textOp1.textContent.text=buildInfo.versionRelease
binding.textOp2.textContent.text=buildInfo.versionSdkInt.toString()
binding.textOp4.textContent.text=buildInfo.securityPatch
@ -152,6 +152,7 @@ mainViewModel.buildInfo.observe(viewLifecycleOwner) { buildInfo ->
deviceInfo ->
stop(binding.swipeRefresh)
deviceInfo?.let {
binding.logoDevice.text=deviceInfo.brand
binding.phoneName.text=deviceInfo.brand
binding.text0.textContent.text=deviceInfo.model
binding.text1.textContent.text=deviceInfo.productName

View File

@ -2,18 +2,26 @@ package com.xyzshell.myphoneinfo.dialog
import android.os.Bundle
import android.view.View
import com.xyzshell.andinfo.libs.BatteryDetails
import com.xyzshell.myphoneinfo.R
import com.xyzshell.myphoneinfo.base.BaseDialogFragment
import com.xyzshell.myphoneinfo.databinding.DialogBatteryBinding
class DialogBattery :BaseDialogFragment<DialogBatteryBinding>(DialogBatteryBinding::inflate){
class DialogBattery(val batteryInfo: BatteryDetails) :BaseDialogFragment<DialogBatteryBinding>(DialogBatteryBinding::inflate){
override fun getTitle(): String = resources.getString(R.string.battery)
override fun getIconRes(): Int? =1
override fun getIconRes(): Int =1
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tv1BatteryLevel.setValue("${batteryInfo.percentage}%")
binding.tv2Temperature.setValue("${batteryInfo.temperature}°C")
binding.tv3Status.setValue(batteryInfo.status)
//todo
// binding.tv4Technology.setValue(batteryInfo.capacity.toString())
binding.tv5Health.setValue(batteryInfo.health)
binding.tv6Voltage.setValue("${batteryInfo.voltage}mV")
binding.tv7Capacity.setValue("${batteryInfo.capacity}mAh")
}
override fun onNegativeClick() {

View File

@ -2,18 +2,26 @@ package com.xyzshell.myphoneinfo.dialog
import android.os.Bundle
import android.view.View
import com.xyzshell.andinfo.libs.BuildInfo
import com.xyzshell.myphoneinfo.R
import com.xyzshell.myphoneinfo.base.BaseDialogFragment
import com.xyzshell.myphoneinfo.databinding.DialogOperatingBinding
class DialogOperating :BaseDialogFragment<DialogOperatingBinding>(DialogOperatingBinding::inflate){
class DialogOperating(val build: BuildInfo) :BaseDialogFragment<DialogOperatingBinding>(DialogOperatingBinding::inflate){
override fun getTitle(): String = resources.getString(R.string.operating_system)
override fun getIconRes(): Int? =7
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tv1BatteryLevel.setValue(build.versionRelease)
binding.tv2Temperature.setValue(build.securityPatch)
binding.tv3Status.setValue(build.buildDate.toString())
binding.tv5Health.setValue(build.kernelCompleteVersion.toString())
binding.tv6Voltage.setValue(build.kernelArchitecture.toString())
//todo 指令集
// binding.tv7Capacity.setValue()
}
override fun onNegativeClick() {

View File

@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.xyzshell.andinfo.AndInfo
import com.xyzshell.andinfo.libs.AppDetails
import com.xyzshell.andinfo.libs.BatteryInfo
import com.xyzshell.andinfo.libs.BluetoothInfo
import com.xyzshell.andinfo.libs.BuildInfo
import com.xyzshell.andinfo.libs.CameraInfo
@ -24,10 +25,16 @@ import com.xyzshell.andinfo.libs.NetworkInfo
import com.xyzshell.andinfo.libs.StorageInfo
import com.xyzshell.myphoneinfo.custom.PermissionChecker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainViewModel: ViewModel() {
class MainViewModel : ViewModel() {
// 刷新状态
private var refreshJob: Job? = null
private var isRefreshing = MutableLiveData(false)
// 硬件相关数据
private val _cpuInfo = MutableLiveData<CpuInfo?>()
val cpuInfo: LiveData<CpuInfo?> = _cpuInfo
@ -46,7 +53,7 @@ class MainViewModel: ViewModel() {
private val _bluetoothInfo = MutableLiveData<BluetoothInfo?>()
val bluetoothInfo: LiveData<BluetoothInfo?> = _bluetoothInfo
private val _inputInfo= MutableLiveData<InputInfo?>()
private val _inputInfo = MutableLiveData<InputInfo?>()
val input: LiveData<InputInfo?> = _inputInfo
// 系统相关数据
@ -60,9 +67,16 @@ class MainViewModel: ViewModel() {
private val _widevineDrmDetail = MutableLiveData<DRMInfo.DRMDetail?>()
val widevineDrmDetail: LiveData<DRMInfo.DRMDetail?> = _widevineDrmDetail
//网络相关
private val networkInfo= AndInfo.instance.network
private val _networkStatus= MutableLiveData<NetworkInfo.NetworkType?>()
// 电池状态
private val _batteryInfo = MutableLiveData<BatteryInfo?>()
val batteryInfo: LiveData<BatteryInfo?> = _batteryInfo
// 电池实时刷新相关
private var lastBatteryRefreshTime = 0L
private val batteryRefreshInterval = 10000L // 10秒刷新一次电池信息
// 网络相关
private val _networkStatus = MutableLiveData<NetworkInfo.NetworkType?>()
val networkStatus: LiveData<NetworkInfo.NetworkType?> = _networkStatus
private val _wifiDetails = MutableLiveData<NetworkInfo.WifiDetails?>()
val wifiDetails: LiveData<NetworkInfo.WifiDetails?> = _wifiDetails
@ -73,29 +87,104 @@ class MainViewModel: ViewModel() {
private val _networkPermissionGranted = MutableLiveData<Boolean>()
val networkPermissionGranted: LiveData<Boolean> = _networkPermissionGranted
// 网络实时刷新相关
private var lastNetworkRefreshTime = 0L
private var lastNetworkType: NetworkInfo.NetworkType? = null
private val networkRefreshInterval = 5000L // 5秒刷新一次网络信息
//应用列表
private val _installedApps= MutableLiveData<List<AppDetails>>()
// 应用列表
private val _installedApps = MutableLiveData<List<AppDetails>>()
val installedApps: LiveData<List<AppDetails>> = _installedApps
//相机相关
// 相机相关
private val _cameraInfo = MutableLiveData<CameraInfo?>()
val cameraInfo: LiveData<CameraInfo?> = _cameraInfo
init{
init {
loadApps()
refreshSystemInfo()
refreshCameraInfo()
refreshHardwareInfo(null) // 首次加载硬件信息
refreshBatteryInfo()
}
fun refreshApps() {
loadApps()
}
/**
* 刷新网络信息带权限检查
* 启动实时刷新只刷新电池和网络
*/
fun refreshNetworkInfo(context: Context){
viewModelScope.launch(Dispatchers.IO){
fun startRealTimeRefresh(context: Context) {
stopRealTimeRefresh() // 确保之前的任务被取消
refreshJob = viewModelScope.launch {
while (true) {
isRefreshing.value = true
// 并行刷新电池和网络
launch { refreshBatteryIfNeeded() }
launch { refreshNetworkIfNeeded(context) }
delay(1000) // 每秒检查一次是否需要刷新
isRefreshing.value = false
}
}
}
/**
* 停止实时刷新
*/
fun stopRealTimeRefresh() {
refreshJob?.cancel()
refreshJob = null
isRefreshing.value = false
}
/**
* 条件刷新电池信息防止频繁刷新
*/
private suspend fun refreshBatteryIfNeeded() {
val currentTime = System.currentTimeMillis()
val timeSinceLastRefresh = currentTime - lastBatteryRefreshTime
// 如果距离上次刷新时间超过间隔,则刷新
if (timeSinceLastRefresh >= batteryRefreshInterval) {
refreshBatteryInfo()
lastBatteryRefreshTime = currentTime
}
}
/**
* 条件刷新网络信息防止频繁刷新
*/
private suspend fun refreshNetworkIfNeeded(context: Context) {
val currentTime = System.currentTimeMillis()
val timeSinceLastRefresh = currentTime - lastNetworkRefreshTime
// 如果距离上次刷新时间超过间隔,则刷新
if (timeSinceLastRefresh >= networkRefreshInterval) {
refreshNetworkInfoOptimized(context)
lastNetworkRefreshTime = currentTime
}
}
/**
* 优化后的电池信息刷新
*/
fun refreshBatteryInfo() {
viewModelScope.launch(Dispatchers.IO) {
try {
val battery = AndInfo.instance.battery
_batteryInfo.postValue(battery)
} catch (e: Exception) {
e.printStackTrace()
// 可以添加错误处理,比如重试机制
}
}
}
/**
* 优化后的网络信息刷新带增量更新
*/
private fun refreshNetworkInfoOptimized(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
// 检查权限
val hasPermissions = PermissionChecker.getMissingPermissions(context).isEmpty()
_networkPermissionGranted.postValue(hasPermissions)
@ -106,8 +195,79 @@ class MainViewModel: ViewModel() {
try {
// 获取网络类型
val networkInfo = AndInfo.instance.network
val newNetworkType = networkInfo.getCurrentNetworkType()
// 只在网络类型变化时更新状态
if (newNetworkType != lastNetworkType) {
_networkStatus.postValue(newNetworkType)
lastNetworkType = newNetworkType
// 网络变化时刷新详细信息
refreshNetworkDetails(networkInfo, newNetworkType)
} else {
// 如果网络类型没变,只检查是否有权限获取详细信息
refreshNetworkDetailsIfNeeded(networkInfo, newNetworkType)
}
} catch (e: Exception) {
e.printStackTrace()
// 可以添加重试逻辑
}
}
}
/**
* 刷新网络详细信息
*/
private fun refreshNetworkDetails(
networkInfo: NetworkInfo,
networkType: NetworkInfo.NetworkType
) {
when (networkType) {
NetworkInfo.NetworkType.WIFI -> {
_wifiDetails.postValue(networkInfo.getWifiDetails())
// WiFi下也尝试获取移动网络信息可能为null
_mobileDetails.postValue(networkInfo.getMobileDetails())
}
NetworkInfo.NetworkType.MOBILE -> {
_mobileDetails.postValue(networkInfo.getMobileDetails())
// 移动网络下也尝试获取WiFi信息可能为null
_wifiDetails.postValue(networkInfo.getWifiDetails())
}
else -> {
_wifiDetails.postValue(null)
_mobileDetails.postValue(null)
}
}
}
/**
* 只在需要时刷新网络详细信息避免频繁调用
*/
private fun refreshNetworkDetailsIfNeeded(
networkInfo: NetworkInfo,
networkType: NetworkInfo.NetworkType
) {
// 这里可以根据需要添加更复杂的逻辑
// 例如WiFi信号强度变化超过一定阈值时才刷新
refreshNetworkDetails(networkInfo, networkType)
}
/**
* 外部调用的刷新网络信息方法保持原有接口
*/
fun refreshNetworkInfo(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
// 检查权限
val hasPermissions = PermissionChecker.getMissingPermissions(context).isEmpty()
_networkPermissionGranted.postValue(hasPermissions)
try {
// 获取网络类型
val networkInfo = AndInfo.instance.network
val type = networkInfo.getCurrentNetworkType()
_networkStatus.postValue(type)
lastNetworkType = type
// 根据网络类型获取详细信息
when (type) {
@ -124,13 +284,35 @@ class MainViewModel: ViewModel() {
_mobileDetails.postValue(null)
}
}
lastNetworkRefreshTime = System.currentTimeMillis()
} catch (e: Exception) {
e.printStackTrace()
// 处理异常
}
}
}
/**
* 刷新所有信息手动触发
*/
fun refreshAll(context: Context) {
viewModelScope.launch {
isRefreshing.value = true
// 并行刷新所有信息
launch { refreshBatteryInfo() }
launch { refreshNetworkInfo(context) }
launch { refreshHardwareInfo(context) }
launch { refreshSystemInfo() }
launch { refreshCameraInfo() }
launch { refreshApps() }
// 等待所有刷新完成
delay(1000) // 给足够时间完成
isRefreshing.value = false
}
}
/**
* 仅检查网络权限
*/
@ -140,69 +322,88 @@ class MainViewModel: ViewModel() {
_networkPermissionGranted.postValue(hasPermissions)
}
}
fun refreshApps() {
loadApps()
}
fun loadApps() {
viewModelScope.launch(Dispatchers.IO){
val apps= AndInfo.instance.app.getInstalledApps()
viewModelScope.launch(Dispatchers.IO) {
val apps = AndInfo.instance.app.getInstalledApps()
_installedApps.postValue(apps)
}
}
/**
* 硬件刷新方法
* */
fun refreshHardwareInfo(context: Context){
viewModelScope.launch(Dispatchers.IO){
*/
fun refreshHardwareInfo(context: Context?) {
viewModelScope.launch(Dispatchers.IO) {
try {
val cpu= async{AndInfo.instance.cpu}
val cpu = async { AndInfo.instance.cpu }
_cpuInfo.postValue(cpu.await())
val gpu= async{AndInfo.instance.gpu}
val gpu = async { AndInfo.instance.gpu }
_gpuInfo.postValue(gpu.await())
val display = async{AndInfo.instance.display}
val display = async { AndInfo.instance.display }
_displayInfo.postValue(display.await())
val storage = async{AndInfo.instance.storage}
val storage = async { AndInfo.instance.storage }
_storageInfo.postValue(storage.await())
val mem = async{AndInfo.instance.memory}
val mem = async { AndInfo.instance.memory }
_memInfo.postValue(mem.await())
// 检查权限
val bluetoothInfo = AndInfo.instance.bluetooth
val inputInfo= async{AndInfo.instance.input}
val inputInfo = async { AndInfo.instance.input }
_inputInfo.postValue(inputInfo.await())
val hasPermissions= bluetoothInfo.requiredPermissions.all { permission ->
// 蓝牙信息需要权限检查
if (context != null) {
val bluetoothInfo = AndInfo.instance.bluetooth
val hasPermissions = bluetoothInfo.requiredPermissions.all { permission ->
ActivityCompat.checkSelfPermission(context, permission) ==
PackageManager.PERMISSION_GRANTED
}
if (!hasPermissions) {
return@launch
}
if (hasPermissions) {
_bluetoothInfo.postValue(bluetoothInfo)
//蓝牙信息
}catch (e: Exception){
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
fun refreshSystemInfo(){
viewModelScope.launch(Dispatchers.IO){
val device = AndInfo.instance.device
_deviceInfo.postValue(device)
val buildInfo = AndInfo.instance.build
_buildInfo.postValue(buildInfo)
val clearkeyDrmDetail = AndInfo.instance.drm.getDrmDetail(DRMInfo.CLEARKEY_UUID)
_clearkeyDrmDetail.postValue(clearkeyDrmDetail)
val widevineDrmDetail = AndInfo.instance.drm.getDrmDetail(DRMInfo.WIDEVINE_UUID)
_widevineDrmDetail.postValue(widevineDrmDetail)
fun refreshSystemInfo() {
viewModelScope.launch(Dispatchers.IO) {
val device = async { AndInfo.instance.device }
_deviceInfo.postValue(device.await())
val buildInfo = async { AndInfo.instance.build }
_buildInfo.postValue(buildInfo.await())
val clearkeyDrmDetail = async { AndInfo.instance.drm.getDrmDetail(DRMInfo.CLEARKEY_UUID) }
_clearkeyDrmDetail.postValue(clearkeyDrmDetail.await())
val widevineDrmDetail = async { AndInfo.instance.drm.getDrmDetail(DRMInfo.WIDEVINE_UUID) }
_widevineDrmDetail.postValue(widevineDrmDetail.await())
}
}
fun refreshCameraInfo(){
viewModelScope.launch(Dispatchers.IO){
fun refreshCameraInfo() {
viewModelScope.launch(Dispatchers.IO) {
val cameraInfo = AndInfo.instance.camera
_cameraInfo.postValue(cameraInfo)
}
}
/**
* 清理资源
*/
override fun onCleared() {
super.onCleared()
stopRealTimeRefresh()
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="3dp" />
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="3dp" />
<solid android:color="@color/module_title_color" /> <!-- 第一段颜色 -->
</shape>
</clip>
</item>
</layer-list>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp" />
<solid android:color="@color/btn_30_trans" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dp" />
<solid android:color="@color/yellow_color" /> <!-- 第二段颜色 -->
</shape>
</clip>
</item>
</layer-list>

View File

@ -23,12 +23,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@mipmap/battery_ic" />
android:src="@mipmap/property_1full" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/icon_battery"
android:layout_marginStart="@dimen/each_item_padding_horizontal"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title_battery"
@ -38,14 +38,43 @@
android:text="@string/battery"
android:textSize="14sp"
android:textColor="@color/black"
android:layout_marginStart="@dimen/each_item_padding_horizontal"
tools:ignore="RelativeOverlap" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="6dp"
android:maxHeight="6dp"
android:minHeight="6dp"
android:padding="0dp"
android:progress="0"
android:progressDrawable="@drawable/progress_bg"
android:thumb="@android:color/transparent"
android:thumbOffset="0dp" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/percent"
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/apps"
android:textSize="12sp" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/battery_content"
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/apps"
tools:ignore="RelativeOverlap" />
android:textSize="10sp"
android:layout_marginStart="@dimen/each_item_padding_horizontal"
/>
</LinearLayout>
@ -70,10 +99,10 @@
android:layout_centerVertical="true"
android:src="@mipmap/stroke_bg" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/icon_storage"
android:layout_marginStart="@dimen/each_item_padding_horizontal"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title_storage"
@ -82,9 +111,37 @@
android:layout_height="wrap_content"
android:text="@string/storage"
android:textSize="14sp"
android:layout_marginStart="@dimen/each_item_padding_horizontal"
android:textColor="@color/black"
tools:ignore="RelativeOverlap" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<SeekBar
android:id="@+id/seekbar1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="6dp"
android:maxHeight="6dp"
android:minHeight="6dp"
android:padding="0dp"
android:progress="0"
android:progressDrawable="@drawable/progress_bg"
android:thumb="@android:color/transparent"
android:thumbOffset="0dp" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/percent1"
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/apps"
android:textSize="12sp" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:layout_marginStart="@dimen/each_item_padding_horizontal"
android:id="@+id/storage_content"
style="@style/LeftContent"
android:layout_width="wrap_content"

View File

@ -11,14 +11,11 @@
android:paddingVertical="@dimen/dashboard_model_padding_vertical"
app:layout_constraintTop_toBottomOf="@id/relayout_tests">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/phone_logo"
style="@style/LeftContent"
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OPPO"
android:layout_marginHorizontal="20dp"
android:layout_centerVertical="true"
tools:ignore="RelativeOverlap" />
@ -36,19 +33,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="Xiaomi Mi"
android:textSize="28sp"
android:textSize="16sp"
tools:ignore="RelativeOverlap" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextWhite"
android:id="@+id/tv_phone_number"
android:layout_width="wrap_content"
android:layout_marginTop="6dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="Xiaomi Mi"
tools:ignore="RelativeOverlap" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextWhiteNormal"
@ -57,9 +44,16 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:textStyle="bold"
android:text="Xiaomi Mi"
android:textSize="12sp"
tools:ignore="RelativeOverlap" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextWhiteNormal"
android:id="@+id/tv_android_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:textSize="12sp"
tools:ignore="RelativeOverlap" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextWhiteNormal"
android:id="@+id/tv_phone_uptime"
@ -67,6 +61,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="@string/uptime"
android:textSize="12sp"
tools:ignore="RelativeOverlap" />
<com.google.android.material.textview.MaterialTextView
@ -76,6 +71,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="@string/deep_sleep"
android:textSize="12sp"
tools:ignore="RelativeOverlap" />

View File

@ -27,8 +27,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv4_technology"
app:labelText="@string/technology"
app:valueText="@string/capacity"/>
app:labelText="@string/technology" />
<com.xyzshell.myphoneinfo.custom.LabelValueCustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -23,12 +23,12 @@
android:layout_height="wrap_content"
android:id="@+id/tv3_status"
app:labelText="@string/build"/>
<com.xyzshell.myphoneinfo.custom.LabelValueCustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv4_technology"
app:labelText="@string/emui"
app:valueText="EmotionUl 13.0.0"/>
<!-- <com.xyzshell.myphoneinfo.custom.LabelValueCustomView-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:id="@+id/tv4_technology"-->
<!-- app:labelText="@string/emui"-->
<!-- app:valueText="EmotionUl 13.0.0"/>-->
<com.xyzshell.myphoneinfo.custom.LabelValueCustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -4,12 +4,42 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.xyzshell.myphoneinfo.custom.LabelValueCustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvRamSize"
app:labelText="@string/ram_size"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginHorizontal="15dp"
android:layout_marginHorizontal="25dp"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ram"
android:textSize="16sp" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/ramSize"
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginHorizontal="25dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
@ -18,8 +48,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="28.01 GB used"
android:textSize="17sp"
android:textStyle="bold" />
android:textSize="14sp" />
<View
android:layout_width="0dp"
@ -32,16 +61,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="128 GB total"
android:textSize="17sp"
android:textStyle="bold" />
android:textSize="14sp" />
</LinearLayout>
<SeekBar
android:id="@+id/seekbar3"
android:layout_width="match_parent"
android:layout_height="10dp"
android:maxHeight="10dp"
android:minHeight="10dp"
android:layout_height="8dp"
android:maxHeight="8dp"
android:minHeight="8dp"
android:padding="0dp"
android:progress="50"
android:progressDrawable="@drawable/progress_bg"
@ -51,174 +79,26 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="15dp">
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:src="@mipmap/radius1" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="@string/apps_and_data"
android:textSize="15sp"
android:textColor="@color/dialog_value_color" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/radius1"
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="18.77 GB"
android:textSize="16sp"
android:textColor="@color/dialog_value_color" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:src="@mipmap/radius2" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="@string/system"
android:textSize="15sp"
android:textColor="@color/dialog_value_color" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/radius2"
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="18.77 GB"
android:textSize="16sp"
android:textColor="@color/dialog_value_color" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:src="@mipmap/radius3" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="@string/free"
android:textSize="15sp"
android:textColor="@color/dialog_value_color" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/radius3"
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="18.77 GB"
android:textSize="16sp"
android:textColor="@color/dialog_value_color" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
style="@style/TextHeavy20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:textSize="15sp"
android:text="@string/internal_storage"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/textTitle"
style="@style/LeftContent"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="@string/filesystem"
android:textStyle="bold" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/textContent"
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:textSize="15sp"
android:text="@string/apps"
tools:ignore="RelativeOverlap" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginHorizontal="25dp"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/data"
android:textSize="18sp"
android:textStyle="bold"
/>
android:text="@string/zram"
android:textSize="16sp" />
<View
android:layout_width="0dp"
@ -226,19 +106,19 @@
android:layout_weight="1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/stor2"
android:id="@+id/zramSize"
style="@style/LeftContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="119 GB"
android:textSize="25sp"
android:textStyle="bold"
/>
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginHorizontal="25dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
@ -246,8 +126,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2.22 GB used"
android:textSize="15sp"
android:textStyle="normal" />
android:textSize="14sp" />
<View
android:layout_width="0dp"
@ -260,16 +139,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3.75 GB free"
android:textSize="15sp"
android:textStyle="normal" />
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
<SeekBar
android:id="@+id/seekbar5"
android:layout_width="match_parent"
android:layout_height="10dp"
android:maxHeight="10dp"
android:minHeight="10dp"
android:layout_height="8dp"
android:maxHeight="8dp"
android:minHeight="8dp"
android:padding="0dp"
android:progress="50"
android:progressDrawable="@drawable/progress_bg"

View File

@ -4,6 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_color"
android:id="@+id/swipeRefresh"
tools:context=".dashboard.BatteryFragment">
<androidx.core.widget.NestedScrollView
@ -68,12 +69,10 @@
android:textAlignment="center" />
<LinearLayout
android:id="@+id/connectData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="15dp"
android:visibility="visible">
android:layout_marginStart="15dp">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/conText1"
@ -85,6 +84,7 @@
tools:ignore="RelativeOverlap" />
<LinearLayout
android:id="@+id/textCurrent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
@ -108,6 +108,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/textPower"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
@ -129,9 +130,33 @@
android:text=" 0.5 W"
tools:ignore="RelativeOverlap" />
</LinearLayout>
<LinearLayout
android:id="@+id/textRemain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
style="@style/LeftContent"
android:textColor="@color/module_title_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/voltage_1"
tools:ignore="RelativeOverlap" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/conTExt5"
style="@style/LeftContent"
android:textColor="@color/module_title_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
tools:ignore="RelativeOverlap" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
@ -165,6 +190,9 @@
<include
android:id="@+id/info5"
layout="@layout/common_text_style" />
<include
android:id="@+id/info6"
layout="@layout/common_text_style" />
</LinearLayout>
</LinearLayout>

View File

@ -222,17 +222,38 @@
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 第一段进度条 -->
<SeekBar
android:id="@+id/seekbar3"
android:id="@+id/seekbarr1"
android:layout_width="match_parent"
android:layout_height="10dp"
android:maxHeight="10dp"
android:minHeight="10dp"
android:padding="0dp"
android:progress="0"
android:progressDrawable="@drawable/progress_bg"
android:thumb="@drawable/progress_oval"
android:thumbOffset="0dp" />
android:progressDrawable="@drawable/progress_second_segment"
android:thumb="@android:color/transparent"
android:thumbOffset="0dp"
android:max="100" />
<!-- 第二段进度条:需要加上第一段的值 -->
<SeekBar
android:id="@+id/seekbarr2"
android:layout_width="match_parent"
android:layout_height="10dp"
android:maxHeight="10dp"
android:minHeight="10dp"
android:padding="0dp"
android:progress="0"
android:progressDrawable="@drawable/progress_first_segment"
android:thumb="@android:color/transparent"
android:thumbOffset="0dp"
android:max="100" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
@ -271,7 +292,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="18.77 GB"
android:text="GB"
android:textColor="@color/right_color"
tools:ignore="RelativeOverlap" />
</LinearLayout>
@ -308,7 +329,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="18.77 GB"
android:text="GB"
android:textColor="@color/right_color"
tools:ignore="RelativeOverlap" />
</LinearLayout>
@ -345,7 +366,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:text="18.77 GB"
android:text="GB"
android:textColor="@color/right_color"
tools:ignore="RelativeOverlap" />
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

View File

@ -294,7 +294,7 @@
<string name="google_play_services_version">Google Play Services version</string>
<string name="toybox">Toybox</string>
<string name="java_VM">Java VM</string>
<string name="current">current</string>
<string name="current">Current</string>
<string name="ae_lock">AE lock</string>
<string name="wb_lock">WB lock</string>
<string name="white_balance_modes">White balance modes</string>
@ -305,6 +305,7 @@
<string name="scanning">Scanning...</string>
<string name="no_devices">No devices</string>
<string name="permissions_required">Bluetooth permission denied.</string>
<string name="net_permissions_required">permission denied.</string>
<string name="bluetooth_not_enabled">Bluetooth is not enabled.</string>
<string name="bluetooth_le">Bluetooth LE (Low Energy)</string>
<string name="multiple_advertisement">Multiple advertisement</string>
@ -335,4 +336,11 @@
<string name="not_ready">Not ready</string>
<string name="disable">Disabled</string>
<string name="enable">Enabled</string>
<string name="full_usb">Full</string>
<string name="charging_usb">Charging</string>
<string name="discharging">Discharging</string>
<string name="voltage_1">Voltage </string>
<string name="capacity_by">Capacity(reported by system) </string>
<string name="charge_count">Charge counter </string>
<string name="charging_cycle">Charging cycle</string>
</resources>