diff --git a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/custom/SetNumberOrWordUtils.kt b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/custom/SetNumberOrWordUtils.kt
index 40736dd..78b9a7f 100644
--- a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/custom/SetNumberOrWordUtils.kt
+++ b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/custom/SetNumberOrWordUtils.kt
@@ -1,5 +1,10 @@
package com.xyzshell.myphoneinfo.custom
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Date
+import java.util.Locale
+import java.util.TimeZone
import kotlin.math.abs
object SetNumberOrWordUtils {
@@ -98,5 +103,36 @@ object SetNumberOrWordUtils {
fun setYesOrNo(boolean: Boolean): String {
return if (boolean) "Yes" else "No"
}
+ // Long 扩展函数:获取格式化日期字符串
+ fun Long.toFormattedDate(
+ pattern: String = "MMMM dd, yyyy h:mm a",
+ timeZone: TimeZone = TimeZone.getDefault()
+ ): String {
+ val sdf = SimpleDateFormat(pattern, Locale.getDefault())
+ sdf.timeZone = timeZone
+ return sdf.format(Date(this))
+ }
+ // 获取各个时间字段的扩展函数
+ fun Long.toCalendar(): Calendar {
+ return Calendar.getInstance().apply {
+ time = Date(this@toCalendar)
+ }
+ }
+
+ fun Long.getYear(): Int = this.toCalendar().get(Calendar.YEAR)
+ fun Long.getMonth(): Int = this.toCalendar().get(Calendar.MONTH) + 1
+ fun Long.getDay(): Int = this.toCalendar().get(Calendar.DAY_OF_MONTH)
+ fun Long.getHour(): Int = this.toCalendar().get(Calendar.HOUR_OF_DAY)
+ fun Long.getMinute(): Int = this.toCalendar().get(Calendar.MINUTE)
+ fun Long.getSecond(): Int = this.toCalendar().get(Calendar.SECOND)
+ fun Long.getMillisecond(): Int = this.toCalendar().get(Calendar.MILLISECOND)
+
+ // Long 扩展函数:获取格式化大小字符串
+ fun Long.toSizeString(): String = when {
+ this < 1000 -> "$this B"
+ this < 1000*1000 -> "%.1f KB".format(this/1000.0)
+ this < 1000*1000*1000 -> "%.1f MB".format(this/(1000.0*1000))
+ else -> "%.1f GB".format(this/(1000.0*1000*1000))
+ }
}
\ No newline at end of file
diff --git a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/AppsFragment.kt b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/AppsFragment.kt
index e8a5bd8..2e4df6e 100644
--- a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/AppsFragment.kt
+++ b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/AppsFragment.kt
@@ -6,6 +6,7 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.xyzshell.andinfo.AndInfo
import com.xyzshell.andinfo.libs.AppDetails
@@ -15,6 +16,10 @@ import com.xyzshell.myphoneinfo.databinding.FragmentAppsBinding
import com.xyzshell.myphoneinfo.dialog.AppDialogFragment
import com.xyzshell.myphoneinfo.dialog.BottomDialogFragment
import com.xyzshell.myphoneinfo.main.MainScrollActivity
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
class AppsFragment : Fragment(),AppListAdapter.OnShowDialogListener {
private lateinit var binding: FragmentAppsBinding
@@ -34,15 +39,25 @@ class AppsFragment : Fragment(),AppListAdapter.OnShowDialogListener {
val adapter= AppListAdapter()
val installedApps = AndInfo.instance.app.getInstalledApps()
val userSize=installedApps.size
- adapter.setList(installedApps)
- adapter.setOnclickListener(this)
+ viewLifecycleOwner.lifecycleScope.launch {
+ delay(50) // 短暂延迟确保UI完成布局
+ withContext(Dispatchers.Main) {
+ adapter.setList(installedApps)
+ adapter.setOnclickListener(this@AppsFragment)
+ }}
binding.recyclerView.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
+ binding.tvTitle.text=when(0){//todo replace with user/system/all/none
+ 0 -> "User($userSize)"
+ 1 -> "System(23)"
+ 2 -> "All(23)"
+ else -> "None"
+ }
binding.llTitle.setOnClickListener {
bottomDialog= BottomDialogFragment(type = "apps", sel = sel, invoke = {item->
sel = item
binding.tvTitle.text=when(item){
- 0 -> "User$userSize"
+ 0 -> "User($userSize)"
1 -> "System(23)"
2 -> "All(23)"
else -> "None"
@@ -66,7 +81,7 @@ class AppsFragment : Fragment(),AppListAdapter.OnShowDialogListener {
}
override fun onShowAppSelectDialog(item: AppDetails) {
- dialogFragment = AppDialogFragment()
+ dialogFragment = AppDialogFragment(item)
dialogFragment.show(requireActivity().supportFragmentManager, "AppDialogFragment")
}
diff --git a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/NetworkFragment.kt b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/NetworkFragment.kt
index f09bc1d..97fe63a 100644
--- a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/NetworkFragment.kt
+++ b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dashboard/NetworkFragment.kt
@@ -9,6 +9,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.RequiresPermission
+import androidx.lifecycle.lifecycleScope
import com.xyzshell.andinfo.AndInfo
import com.xyzshell.andinfo.libs.NetworkInfo
import com.xyzshell.myphoneinfo.R
@@ -17,6 +18,10 @@ import com.xyzshell.myphoneinfo.custom.SetNumberOrWordUtils.getHoursString
import com.xyzshell.myphoneinfo.custom.SetNumberOrWordUtils.setYesOrNo
import com.xyzshell.myphoneinfo.databinding.FragmentNetworkBinding
import com.xyzshell.myphoneinfo.dialog.ShowLoadFragment
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import kotlin.toString
class NetworkFragment : Fragment() {
@@ -42,69 +47,74 @@ private lateinit var binding:FragmentNetworkBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
networkInfo= AndInfo.instance.network
- refreshStatus()
- if(PermissionChecker.getMissingPermissions(context = requireContext()).isNotEmpty()){
- PermissionChecker.requestSimple(
- requireActivity(),
- onGranted = {
- // 权限已授予,执行操作
- refreshStatus()
- },
- onDenied = {
- // 权限被拒绝
- Toast.makeText(context, getString(R.string.permissions_required), Toast.LENGTH_SHORT).show()
+ viewLifecycleOwner.lifecycleScope.launch {
+ delay(50) // 短暂延迟确保UI完成布局
+ withContext(Dispatchers.Main) {
+ refreshStatus()
+ if(PermissionChecker.getMissingPermissions(context = requireContext()).isNotEmpty()){
+ PermissionChecker.requestSimple(
+ requireActivity(),
+ onGranted = {
+ // 权限已授予,执行操作
+ refreshStatus()
+ },
+ onDenied = {
+ // 权限被拒绝
+ Toast.makeText(context, getString(R.string.permissions_required), Toast.LENGTH_SHORT).show()
+ }
+ )
}
- )
- }
- //wifi
- binding.networkLayout.wfText1.textTitle.text=getString(R.string.status)
+ //wifi
+ binding.networkLayout.wfText1.textTitle.text=getString(R.string.status)
// binding.networkLayout.wfText2.textTitle.text=getString(R.string.network)
- binding.networkLayout.wfText3.textTitle.text=getString(R.string.bssid)
- binding.networkLayout.wfText4.textTitle.text=getString(R.string.function)
- binding.networkLayout.wfText5.textTitle.text=getString(R.string.connection_speed)
- binding.networkLayout.wfText6.textTitle.text=getString(R.string.signal_strength)
- binding.networkLayout.wfText7.textTitle.text=getString(R.string.frequency)
- binding.networkLayout.wfText8.textTitle.text=getString(R.string.channel)
- binding.networkLayout.wfText10.textTitle.text=getString(R.string.standard)
+ binding.networkLayout.wfText3.textTitle.text=getString(R.string.bssid)
+ binding.networkLayout.wfText4.textTitle.text=getString(R.string.function)
+ binding.networkLayout.wfText5.textTitle.text=getString(R.string.connection_speed)
+ binding.networkLayout.wfText6.textTitle.text=getString(R.string.signal_strength)
+ binding.networkLayout.wfText7.textTitle.text=getString(R.string.frequency)
+ binding.networkLayout.wfText8.textTitle.text=getString(R.string.channel)
+ binding.networkLayout.wfText10.textTitle.text=getString(R.string.standard)
- //dhcp
- binding.networkLayout.dhText1.textTitle.text=getString(R.string.dhcp_server)
- binding.networkLayout.dhText2.textTitle.text=getString(R.string.dhcp_lease_time)
- binding.networkLayout.dhText3.textTitle.text=getString(R.string.gateway)
- binding.networkLayout.dhText4.textTitle.text=getString(R.string.subnet_mask)
- binding.networkLayout.dhText5.textTitle.text=getString(R.string.dns1)
- binding.networkLayout.dhText6.textTitle.text=getString(R.string.dns2)
- binding.networkLayout.dhText7.textTitle.text=getString(R.string.ip_address)
- binding.networkLayout.dhText8.textTitle.text=getString(R.string.ipv6)
+ //dhcp
+ binding.networkLayout.dhText1.textTitle.text=getString(R.string.dhcp_server)
+ binding.networkLayout.dhText2.textTitle.text=getString(R.string.dhcp_lease_time)
+ binding.networkLayout.dhText3.textTitle.text=getString(R.string.gateway)
+ binding.networkLayout.dhText4.textTitle.text=getString(R.string.subnet_mask)
+ binding.networkLayout.dhText5.textTitle.text=getString(R.string.dns1)
+ binding.networkLayout.dhText6.textTitle.text=getString(R.string.dns2)
+ binding.networkLayout.dhText7.textTitle.text=getString(R.string.ip_address)
+ binding.networkLayout.dhText8.textTitle.text=getString(R.string.ipv6)
- //Hardware
- binding.networkLayout.hardCheck1.content.text=getString(R.string.standard_all)
- binding.networkLayout.hardCheck2.content.text=getString(R.string.wifi_direct_support)
- binding.networkLayout.hardCheck3.content.text=getString(R.string.wifi_aware_support)
- binding.networkLayout.hardCheck4.content.text=getString(R.string.wifi_passpoint_support)
- binding.networkLayout.hardCheck5.content.text=getString(R.string.ghz_band_support)
- binding.networkLayout.hardCheck6.content.text=getString(R.string.ghz6_band_support)
+ //Hardware
+ binding.networkLayout.hardCheck1.content.text=getString(R.string.standard_all)
+ binding.networkLayout.hardCheck2.content.text=getString(R.string.wifi_direct_support)
+ binding.networkLayout.hardCheck3.content.text=getString(R.string.wifi_aware_support)
+ binding.networkLayout.hardCheck4.content.text=getString(R.string.wifi_passpoint_support)
+ binding.networkLayout.hardCheck5.content.text=getString(R.string.ghz_band_support)
+ binding.networkLayout.hardCheck6.content.text=getString(R.string.ghz6_band_support)
- //mobel
- binding.mdText1.textTitle.text=getString(R.string.dual_sim_dual_standby)
- binding.mdText2.textTitle.text=getString(R.string.phone_type)
- binding.mdText3.textTitle.text=getString(R.string.esim)
+ //mobel
+ binding.mdText1.textTitle.text=getString(R.string.dual_sim_dual_standby)
+ binding.mdText2.textTitle.text=getString(R.string.phone_type)
+ binding.mdText3.textTitle.text=getString(R.string.esim)
- binding.conTexts.textTitle.text=getString(R.string.status)
+ binding.conTexts.textTitle.text=getString(R.string.status)
- binding.defText1.textTitle.text=getString(R.string.data)
+ binding.defText1.textTitle.text=getString(R.string.data)
- binding.defText2.textTitle.text=getString(R.string.voice)
- binding.defText3.textTitle.text=getString(R.string.short_message)
+ binding.defText2.textTitle.text=getString(R.string.voice)
+ binding.defText3.textTitle.text=getString(R.string.short_message)
- binding.networkLayout.pubShow.setOnClickListener{
- val tag = "showLoadFragment"
- if (requireActivity().supportFragmentManager.findFragmentByTag(tag) == null) {
- val showLoadFragment = ShowLoadFragment()
- showLoadFragment.show(requireActivity().supportFragmentManager, tag)
- }
- }
+ binding.networkLayout.pubShow.setOnClickListener{
+ val tag = "showLoadFragment"
+ if (requireActivity().supportFragmentManager.findFragmentByTag(tag) == null) {
+ val showLoadFragment = ShowLoadFragment()
+ showLoadFragment.show(requireActivity().supportFragmentManager, tag)
+ }
+ }
+ }}
+
}
private fun refreshStatus() {
diff --git a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dialog/AppDialogFragment.kt b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dialog/AppDialogFragment.kt
index 821c41f..0528b62 100644
--- a/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dialog/AppDialogFragment.kt
+++ b/myphoneinfo/src/main/java/com/xyzshell/myphoneinfo/dialog/AppDialogFragment.kt
@@ -1,23 +1,39 @@
package com.xyzshell.myphoneinfo.dialog
import android.graphics.Color
+import android.graphics.drawable.Drawable
import android.os.Bundle
+import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
+import android.widget.LinearLayout
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
+import com.xyzshell.andinfo.libs.AppDetails
+import com.xyzshell.myphoneinfo.R
+import com.xyzshell.myphoneinfo.custom.SetNumberOrWordUtils.toFormattedDate
+import com.xyzshell.myphoneinfo.custom.SetNumberOrWordUtils.toSizeString
+import com.xyzshell.myphoneinfo.databinding.CommonCheckStyle2Binding
import com.xyzshell.myphoneinfo.databinding.DialogAppClickBinding
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
-class AppDialogFragment : DialogFragment() {
+class AppDialogFragment(var appInfo:AppDetails) : DialogFragment() {
private var _binding: DialogAppClickBinding? = null
private val baseBinding get() = _binding!!
+ private lateinit var appDetails:AppDetails
- open fun onPositiveClick() {}
+ open fun onPositiveClick() {
+
+ }
override fun onCreateView(
inflater: LayoutInflater,
@@ -25,18 +41,74 @@ class AppDialogFragment : DialogFragment() {
savedInstanceState: Bundle?
): View {
_binding = DialogAppClickBinding.inflate(inflater, container, false)
+ appDetails = appInfo
return baseBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
-
+ setBasicAppInfo()
+ loadPermissionsAsync()
baseBinding.textCancel.setOnClickListener {
onPositiveClick()
dismiss()
}
+ baseBinding.textManage.setOnClickListener {
+ dismiss()
+ }
}
+ private fun loadPermissionsAsync() {
+ viewLifecycleOwner.lifecycleScope.launch {
+ delay(50) // 短暂延迟确保UI完成布局
+ withContext(Dispatchers.Main) {
+ appDetails.permissions.forEach {
+ //允许
+ val allowedView= LayoutInflater.from(context).inflate(R.layout.common_check_style2,baseBinding.allowedLL,false)
+ val allowedBinding = CommonCheckStyle2Binding.bind(allowedView)
+ //不允许
+ val notAllowedView= LayoutInflater.from(context).inflate(R.layout.common_check_style1,baseBinding.notAllowedLL,false)
+ val notAllowedBinding = CommonCheckStyle2Binding.bind(notAllowedView)
+ //特殊
+ val specialView= LayoutInflater.from(context).inflate(R.layout.common_check_style3,baseBinding.specialLL,false)
+ val specialBinding = CommonCheckStyle2Binding.bind(specialView)
+ when(it.status){
+ "Allowed"->{
+ baseBinding.allowedTv.visibility = View.VISIBLE
+ allowedBinding.content.text = it.name
+ baseBinding.allowedLL.addView(allowedView)
+ }
+ "Denied"->{
+ baseBinding.notAllowedTv.visibility = View.VISIBLE
+ notAllowedBinding.content.text = it.name
+ baseBinding.notAllowedLL.addView(notAllowedView)
+ }
+ "Special Access"->{
+ baseBinding.specialTv.visibility = View.VISIBLE
+ specialBinding.content.text = it.name
+ baseBinding.specialLL.addView(specialView)
+ }
+ }
+ Log.d("AppDialogFragment", it.status)
+ }
+ }}
+
+ }
+
+ private fun setBasicAppInfo() {
+ baseBinding.imageIcon.setImageDrawable(appDetails.icon as? Drawable)
+ baseBinding.dialogTitle.text = appDetails.appName
+ baseBinding.tv1.setValue(appDetails.packageName)
+ baseBinding.tv2.setValue(appDetails.versionName.toString())
+ baseBinding.tv3.setValue(appDetails.targetSdkVersion.toString())
+ baseBinding.tv4.setValue(appDetails.minSdkVersion.toString())
+// todo baseBinding.tv5.setValue(appDetails.packageName)
+ baseBinding.tv6.setValue(appDetails.installer.toString())
+ baseBinding.tv7.setValue(appDetails.size.toSizeString())
+ baseBinding.tv8.setValue(appDetails.uid.toString())
+ baseBinding.tv9.setValue("${appDetails.lastUpdateTime.toFormattedDate(pattern = "MMM dd, yyyy h:mm a")}")
+
+ }
override fun onStart() {
super.onStart()
dialog?.window?.let { window ->
@@ -56,4 +128,6 @@ class AppDialogFragment : DialogFragment() {
super.onDestroyView()
_binding = null
}
+
+
}
\ No newline at end of file
diff --git a/myphoneinfo/src/main/res/layout/common_dialog_item.xml b/myphoneinfo/src/main/res/layout/common_dialog_item.xml
index 119fdeb..e392793 100644
--- a/myphoneinfo/src/main/res/layout/common_dialog_item.xml
+++ b/myphoneinfo/src/main/res/layout/common_dialog_item.xml
@@ -34,7 +34,6 @@
android:layout_alignTop="@id/tv_label"
android:layout_marginStart="35dp"
android:layout_toEndOf="@id/tv_label"
- android:gravity="center"
android:textSize="15sp"
android:textColor="#C1C5C2"
android:text="sppppppppppppppppppppp" />
diff --git a/myphoneinfo/src/main/res/layout/dialog_app_click.xml b/myphoneinfo/src/main/res/layout/dialog_app_click.xml
index c0a8750..6b501f0 100644
--- a/myphoneinfo/src/main/res/layout/dialog_app_click.xml
+++ b/myphoneinfo/src/main/res/layout/dialog_app_click.xml
@@ -1,44 +1,53 @@
-
-
-
-
-
-
+
+ android:paddingBottom="35dp"
+ >
+
+
+
+
+
+
+
-
-
-
+
+
@@ -219,4 +236,4 @@
/>
-
+
diff --git a/myphoneinfo/src/main/res/layout/fragment_apps.xml b/myphoneinfo/src/main/res/layout/fragment_apps.xml
index 1b14421..1fe888b 100644
--- a/myphoneinfo/src/main/res/layout/fragment_apps.xml
+++ b/myphoneinfo/src/main/res/layout/fragment_apps.xml
@@ -35,7 +35,7 @@
android:layout_width="wrap_content"
android:id="@+id/tvTitle"
android:layout_height="wrap_content"
- android:text="User apps (23)"
+ android:text=""
style="@style/TextHeavy20"
android:textSize="16sp"
/>
diff --git a/myphoneinfo/src/main/res/layout/item_app_list.xml b/myphoneinfo/src/main/res/layout/item_app_list.xml
index 4b75675..3fa9e00 100644
--- a/myphoneinfo/src/main/res/layout/item_app_list.xml
+++ b/myphoneinfo/src/main/res/layout/item_app_list.xml
@@ -1,6 +1,7 @@
-
Minimum SDK
Installer type
Installed
+ Last updated time
UID
Permissions
Allowed