优化2
This commit is contained in:
parent
ea7c977f62
commit
d937ad854d
|
|
@ -0,0 +1,217 @@
|
||||||
|
package com.stand.standapp.utils
|
||||||
|
|
||||||
|
import android.app.ActivityManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Environment
|
||||||
|
import android.os.Process
|
||||||
|
import android.os.StatFs
|
||||||
|
import org.json.JSONObject
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.net.NetworkInterface
|
||||||
|
import java.util.Collections
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
object DeviceInfoUtils {
|
||||||
|
|
||||||
|
fun getDeviceInfoJson(context: Context): JSONObject {
|
||||||
|
val json = JSONObject()
|
||||||
|
val appContext = context.applicationContext
|
||||||
|
|
||||||
|
// Base App info is typically set at the caller level, but we populate core details
|
||||||
|
try {
|
||||||
|
json.put("model", Build.MODEL)
|
||||||
|
json.put("osVersion", Build.VERSION.RELEASE)
|
||||||
|
|
||||||
|
val abis = Build.SUPPORTED_ABIS
|
||||||
|
json.put("cpuAbi", abis.joinToString(","))
|
||||||
|
|
||||||
|
val is64Bit = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
Process.is64Bit()
|
||||||
|
} else {
|
||||||
|
abis.any { it.contains("64") }
|
||||||
|
}
|
||||||
|
json.put("is64Bit", is64Bit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get base device info")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Screen and display info
|
||||||
|
try {
|
||||||
|
val screenObj = JSONObject()
|
||||||
|
val metrics = appContext.resources.displayMetrics
|
||||||
|
val widthPixels = metrics.widthPixels
|
||||||
|
val heightPixels = metrics.heightPixels
|
||||||
|
val xdpi = metrics.xdpi
|
||||||
|
val ydpi = metrics.ydpi
|
||||||
|
|
||||||
|
screenObj.put("width", widthPixels)
|
||||||
|
screenObj.put("height", heightPixels)
|
||||||
|
screenObj.put("density", metrics.density)
|
||||||
|
screenObj.put("densityDpi", metrics.densityDpi)
|
||||||
|
|
||||||
|
val physicalSize = if (xdpi > 0 && ydpi > 0) {
|
||||||
|
val widthInches = widthPixels / xdpi
|
||||||
|
val heightInches = heightPixels / ydpi
|
||||||
|
Math.sqrt((widthInches * widthInches + heightInches * heightInches).toDouble())
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
screenObj.put("physicalSize", Math.round(physicalSize * 10.0) / 10.0) // 1 decimal place
|
||||||
|
|
||||||
|
json.put("screen", screenObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get screen metrics")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Hardware and manufacturer info
|
||||||
|
try {
|
||||||
|
val hwObj = JSONObject()
|
||||||
|
hwObj.put("manufacturer", Build.MANUFACTURER)
|
||||||
|
hwObj.put("brand", Build.BRAND)
|
||||||
|
hwObj.put("hardware", Build.HARDWARE)
|
||||||
|
hwObj.put("fingerprint", Build.FINGERPRINT)
|
||||||
|
json.put("hardware", hwObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get hardware info")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. System and Locale environment
|
||||||
|
try {
|
||||||
|
val sysObj = JSONObject()
|
||||||
|
sysObj.put("sdkVersion", Build.VERSION.SDK_INT)
|
||||||
|
sysObj.put("language", Locale.getDefault().language)
|
||||||
|
sysObj.put("country", Locale.getDefault().country)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
sysObj.put("securityPatch", Build.VERSION.SECURITY_PATCH)
|
||||||
|
} else {
|
||||||
|
sysObj.put("securityPatch", "")
|
||||||
|
}
|
||||||
|
json.put("system", sysObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get system info")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Memory Info (RAM)
|
||||||
|
try {
|
||||||
|
val memObj = JSONObject()
|
||||||
|
val actManager = appContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||||
|
val memInfo = ActivityManager.MemoryInfo()
|
||||||
|
actManager.getMemoryInfo(memInfo)
|
||||||
|
memObj.put("totalRam", memInfo.totalMem)
|
||||||
|
memObj.put("availRam", memInfo.availMem)
|
||||||
|
json.put("memory", memObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get memory info")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Storage Info
|
||||||
|
try {
|
||||||
|
val storageObj = JSONObject()
|
||||||
|
val path = Environment.getDataDirectory()
|
||||||
|
val stat = StatFs(path.path)
|
||||||
|
val blockSize = stat.blockSizeLong
|
||||||
|
val totalBlocks = stat.blockCountLong
|
||||||
|
val availableBlocks = stat.availableBlocksLong
|
||||||
|
|
||||||
|
storageObj.put("totalInternal", totalBlocks * blockSize)
|
||||||
|
storageObj.put("availInternal", availableBlocks * blockSize)
|
||||||
|
json.put("storage", storageObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get storage info")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Network state
|
||||||
|
try {
|
||||||
|
val netObj = JSONObject()
|
||||||
|
val connManager = appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
|
var networkType = "NONE"
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
val activeNetwork = connManager.activeNetwork
|
||||||
|
val capabilities = connManager.getNetworkCapabilities(activeNetwork)
|
||||||
|
if (capabilities != null) {
|
||||||
|
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
||||||
|
networkType = "WIFI"
|
||||||
|
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
|
||||||
|
networkType = "CELLULAR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val activeNetworkInfo = connManager.activeNetworkInfo
|
||||||
|
if (activeNetworkInfo != null && activeNetworkInfo.isConnected) {
|
||||||
|
if (activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI) {
|
||||||
|
networkType = "WIFI"
|
||||||
|
} else if (activeNetworkInfo.type == ConnectivityManager.TYPE_MOBILE) {
|
||||||
|
networkType = "CELLULAR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
netObj.put("type", networkType)
|
||||||
|
|
||||||
|
var ipAddress = ""
|
||||||
|
try {
|
||||||
|
val interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
|
||||||
|
for (intf in interfaces) {
|
||||||
|
val addrs = Collections.list(intf.inetAddresses)
|
||||||
|
for (addr in addrs) {
|
||||||
|
if (!addr.isLoopbackAddress) {
|
||||||
|
val sAddr = addr.hostAddress ?: continue
|
||||||
|
val isIPv4 = sAddr.indexOf(':') < 0
|
||||||
|
if (isIPv4) {
|
||||||
|
ipAddress = sAddr
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ipAddress.isNotEmpty()) break
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").w(e, "Failed to resolve IP address")
|
||||||
|
}
|
||||||
|
netObj.put("ipAddress", ipAddress)
|
||||||
|
json.put("network", netObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get network status")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Battery status
|
||||||
|
try {
|
||||||
|
val batObj = JSONObject()
|
||||||
|
val batteryStatus: Intent? = appContext.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||||
|
val level = batteryStatus?.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, -1) ?: -1
|
||||||
|
val scale = batteryStatus?.getIntExtra(android.os.BatteryManager.EXTRA_SCALE, -1) ?: -1
|
||||||
|
val batteryPct = if (level >= 0 && scale > 0) (level * 100 / scale.toFloat()).toInt() else -1
|
||||||
|
batObj.put("level", batteryPct)
|
||||||
|
|
||||||
|
val status = batteryStatus?.getIntExtra(android.os.BatteryManager.EXTRA_STATUS, -1) ?: -1
|
||||||
|
val statusString = when (status) {
|
||||||
|
android.os.BatteryManager.BATTERY_STATUS_CHARGING -> "charging"
|
||||||
|
android.os.BatteryManager.BATTERY_STATUS_DISCHARGING -> "discharging"
|
||||||
|
android.os.BatteryManager.BATTERY_STATUS_FULL -> "full"
|
||||||
|
android.os.BatteryManager.BATTERY_STATUS_NOT_CHARGING -> "not_charging"
|
||||||
|
else -> "unknown"
|
||||||
|
}
|
||||||
|
batObj.put("status", statusString)
|
||||||
|
|
||||||
|
val chargePlug = batteryStatus?.getIntExtra(android.os.BatteryManager.EXTRA_PLUGGED, -1) ?: -1
|
||||||
|
val plugString = when (chargePlug) {
|
||||||
|
android.os.BatteryManager.BATTERY_PLUGGED_AC -> "ac"
|
||||||
|
android.os.BatteryManager.BATTERY_PLUGGED_USB -> "usb"
|
||||||
|
android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS -> "wireless"
|
||||||
|
else -> "none"
|
||||||
|
}
|
||||||
|
batObj.put("plugged", plugString)
|
||||||
|
json.put("battery", batObj)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("DeviceInfoUtils").e(e, "Failed to get battery info")
|
||||||
|
}
|
||||||
|
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue