欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android相關(guān)硬件信息的獲取方式整理匯總

 更新時間:2025年05月07日 09:34:54   作者:Coffeeee  
在Android系統(tǒng)中,獲取硬件信息是開發(fā)者經(jīng)常需要進行的操作,特別是在開發(fā)與硬件性能密切相關(guān)的應(yīng)用時,在深入探討如何獲取Android設(shè)備的硬件信息之前,我們首先需要了解一些基本概念和方法,感興趣的小伙伴跟著小編一起來看看吧

最近需要做個項目,里面涉及到一些收集Android硬件信息,雖說項目還沒開始,但也不影響自己先事先準備起來.

檢測是手機還是平板

Android中沒有提供特定的方法來判斷設(shè)備是手機還是平板,只能通過別的方式來間接判斷,比如通過判斷屏幕尺寸

infoText.text = checkIsTablet()

private fun checkIsTablet(): String {
    val metrics = resources.displayMetrics
    val widthInches = metrics.widthPixels / metrics.xdpi
    val heightInches = metrics.heightPixels / metrics.ydpi
    val diagonalInches = sqrt(widthInches.pow(2.0f) + heightInches.pow(2.0f))
    return if (diagonalInches >= 7.0) {
        "手機還是平板:平板"
    } else {
        "手機還是平板:手機"
    }
}

驗證一下,分別將這段代碼運行在一個手機模擬器上以及平板模擬器上,結(jié)果如下

判斷是否為折疊屏

其實在折疊屏沒出現(xiàn)的時候,判斷手機或者是平板使用上述方法還是夠用的,但是在折疊屏面前就顯得信心不足了,折疊屏一展開,那就是一個長著平板臉的手機,為了識別折疊屏,Android10出來了一個新的感應(yīng)器類型TYPE_HINGE_ANGLE,可以通過是否存在這種感應(yīng)器來識別折疊屏

private fun checkIsFoldScreen(): String {
    val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    val hingeAngleSensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
    return if (hingeAngleSensor == null) {
        "是否折疊屏:否"
    } else {
        "是否折疊屏: 是"
    }
}

裝了一個折疊屏的模擬器,拿來試一下看看能不能識別

如果說想要具體拿到折疊屏的狀態(tài),比如是全展開還是半展開,或者收起狀態(tài),就要使用Jetpack WindowManager這個庫了,分別可以通過以下api拿到不同的狀態(tài)

不過這個得用真機試了,模擬器上拿不到FoldingFeature,等我買了折疊屏再試下

屏幕密度與密度比例

這兩個值相信基本每個項目都會用到,屏幕密度一般用來判斷屏幕適配,加載不同的圖片資源,密度比例一般用來單位換算,這倆值都可以通過DisplayMetrics來獲得

infoText.text = checkScreenDpiAndDensity()

private fun checkScreenDpiAndDensity(): String {
    val displayMetric = resources.displayMetrics
    val dpi = displayMetric.densityDpi
    val density = displayMetric.density
    return "屏幕密度:${dpi}  密度比例:${density}"
}

屏幕像素

private fun checkScreenPixel(): String {
    val displayMetrics = DisplayMetrics()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        display?.getRealMetrics(displayMetrics)
    }else{
        windowManager.defaultDisplay.getRealMetrics(displayMetrics);
    }
    val wPixel = displayMetrics.widthPixels
    val hPixel = displayMetrics.heightPixels
    return "像素(寬):${wPixel} 像素(高):${hPixel}"
}

物理尺寸

物理尺寸在安卓上單位是英寸,它表示一個屏幕對角線的長度,至于如何計算對角線,就要用到上學(xué)時候用到的勾股定理,x,y分別是屏幕的寬高,注意的是由于單位是英寸,所以也要把上面計算出來的像素轉(zhuǎn)換成英寸,具體代碼如下

private fun checkPhysicalSize(): String {
    val displayMetrics = DisplayMetrics()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        display?.getRealMetrics(displayMetrics)
    }else{
        windowManager.defaultDisplay.getRealMetrics(displayMetrics);
    }
    val widthInches = displayMetrics.widthPixels / displayMetrics.xdpi
    val heightInches = displayMetrics.heightPixels / displayMetrics.ydpi
    val diagonalInches = sqrt(
        widthInches.pow(2.0f) + heightInches.pow(2.0f)
    )
    return "物理尺寸 $diagonalInches"
}

刷新率

刷新率一般就是指Android屏幕上每秒更新畫面的頻率,單位是赫茲,正常來講,普通設(shè)備的刷新率都為60赫茲,獲取刷新率的代碼如下

private fun checkRefreshRate(): String {
    val mDisplay = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        display
    }else{
        windowManager.defaultDisplay
    }
    return "刷新率 ${mDisplay?.refreshRate}"
}

廣色域

有的設(shè)備支持廣色域,有的設(shè)備僅僅支持標準色域,廣色域的意思是屏幕可以顯示比標準色域(sRGB)更加豐富的顏色范圍,判斷一個設(shè)備是否支持廣色域的方式如下

private fun checkColorGamut(): String {
    val config: Configuration = resources.configuration
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val isWideColorGamut: Boolean = config.isScreenWideColorGamut
        val support = if(isWideColorGamut) "支持" else "不支持"
        return "是否支持廣色域模式:${support}"
    }
    return "不支持廣色域"
}

獲取內(nèi)存(Runtime)

一般來講應(yīng)用想獲取內(nèi)存信息,用的最多的就是通過Runtime來獲取,可以通過它獲取應(yīng)用最大可用內(nèi)存,當前分配的內(nèi)存,當前空閑內(nèi)存,已使用內(nèi)存

infoText.text = checkMemoryRuntime()

private fun checkMemoryRuntime(): String {
    val runtime = Runtime.getRuntime()
    val maxMemory = runtime.maxMemory() // 應(yīng)用最大可用內(nèi)存
    val totalMemory = runtime.totalMemory() // 當前分配的內(nèi)存
    val freeMemory = runtime.freeMemory() // 當前空閑內(nèi)存
    val usedMemory = totalMemory - freeMemory // 已使用內(nèi)存
    return "最大可用內(nèi)存:${maxMemory} 當前分配的內(nèi)存:${totalMemory} 當前空閑內(nèi)存:${freeMemory} 已使用內(nèi)存${usedMemory}"
}

獲取內(nèi)存(MemoryInfo)

還有一種方式就是通過獲取MemoryInfo來拿到內(nèi)存信息,比如總內(nèi)存,當前空閑內(nèi)存以及判斷內(nèi)存是否過低

infoText.text = checkMemoryMemoInfo()

private fun checkMemoryMemoInfo(): String {
    val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    val memoryInfo = ActivityManager.MemoryInfo()
    activityManager.getMemoryInfo(memoryInfo)
    val totalMem = memoryInfo.totalMem
    val availMem = memoryInfo.availMem
    val lowMemory = memoryInfo.lowMemory
    return "總內(nèi)存:${totalMem} 當前空閑內(nèi)存:${availMem} 內(nèi)存是否過低${lowMemory}"
}

磁盤空間(外部存儲與內(nèi)部存儲)

可以通過StatFs來獲取外部存儲以及內(nèi)存存儲容量

//外部存儲
infoText.text = checkExternalStorageInfo()

private fun checkExternalStorageInfo(): String {
    if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
        val path = Environment.getExternalStorageDirectory() // 外部存儲根目錄
        val stat = StatFs(path.path)
        val blockSize = stat.blockSizeLong
        val totalBlocks = stat.blockCountLong
        val availableBlocks = stat.availableBlocksLong
        val totalSize = blockSize * totalBlocks
        val availableSize = blockSize * availableBlocks
        val usedSize = totalSize - availableSize
        return "外部存儲總?cè)萘?${totalSize} 外部存儲可用容量:${availableSize} 外部存儲已用容量:${usedSize}"
    }
    return ""
}

//內(nèi)部存儲
infoText.text = checkInternalStorageInfo()

private fun checkInternalStorageInfo(): String {
    val path = Environment.getDataDirectory() // 內(nèi)部存儲根目錄
    val stat = StatFs(path.path)
    val blockSize = stat.blockSizeLong // 每個block的大小
    val totalBlocks = stat.blockCountLong // 總block數(shù)
    val availableBlocks = stat.availableBlocksLong // 可用block數(shù)

    val totalSize = blockSize * totalBlocks // 總?cè)萘?
    val availableSize = blockSize * availableBlocks // 可用容量
    val usedSize = totalSize - availableSize // 已用容量
    return "內(nèi)部存儲總?cè)萘?${totalSize} 內(nèi)部存儲可用容量:${availableSize} 內(nèi)部存儲已用容量:${usedSize}"
}

CPU內(nèi)核數(shù)量

獲取CPU的內(nèi)核數(shù)量很簡單,Runtime類中有現(xiàn)成的方法

infoText.text = checkCPUcoreNumber()

private fun checkCPUcoreNumber() = 
     "cpu核心數(shù) : ${Runtime.getRuntime().availableProcessors()}"

CPU架構(gòu)

infoText.text = checkCPUArchitecture()
private fun checkCPUArchitecture() =
     "cpu架構(gòu):${Build.SUPPORTED_ABIS[0]}"

CPU硬件信息

infoText.text = checkCPUHardware()
private fun checkCPUHardware() = 
        "硬件信息:${Build.HARDWARE}"

檢測設(shè)備是否root

同樣的沒有任何api可以直接去判斷設(shè)備是否有root權(quán)限,我們只能從以下幾個方式去判斷

  • 判斷檢查是否存在相關(guān)root文件
var fileRooted = false
val paths = arrayOf(
    "/system/app/Superuser.apk",
    "/sbin/su",
    "/system/bin/su",
    "/system/xbin/su",
    "/data/local/xbin/su",
    "/data/local/bin/su",
    "/system/sd/xbin/su",
    "/system/bin/failsafe/su",
    "/data/local/su",
    "/su/bin/su"
)
for (path in paths) {
    if (File(path).exists()) {
        fileRooted = true
    }
}
  • 檢查是否存在su命令
var suCmdExest = false
var process: Process? = null
try {
    process = Runtime.getRuntime().exec(arrayOf("which", "su"))
    val reader = BufferedReader(InputStreamReader(process.inputStream))
    suCmdExest = reader.readLine() != null
} catch (e: Exception) {
    suCmdExest = false
} finally {
    process?.destroy()
}
  • 檢查Build.TAGS里面是否存在test-keys
var testKeys = false
val buildTags = Build.TAGS
testKeys = buildTags != null && buildTags.contains("test-keys")
  • 執(zhí)行su命令
var suCmdExecute = false
var suprocess: Process? = null
try {
    suprocess = Runtime.getRuntime().exec("su")
    val out = suprocess.outputStream
    out.write("exit\n".toByteArray())
    out.flush()
    out.close()
    suCmdExecute = suprocess.waitFor() == 0
} catch (e: java.lang.Exception) {
    suCmdExecute = false
} finally {
    process?.destroy()
}
  • Magisk 文件是否存在
var giskFile = false
val magiskPaths = arrayOf(
    "/sbin/.magisk",
    "/sbin/magisk",
    "/cache/.disable_magisk",
    "/cache/magisk.log",
    "/data/adb/magisk",
    "/data/adb/modules",
    "/data/magisk",
    "/data/magisk.img"
)

for (path in magiskPaths) {
    if (File(path).exists()) {
        giskFile = true
    }
}

保險起見,可以把上述幾個變量放在一起判斷設(shè)備是否有root權(quán)限

val gotRoot = fileRooted || suCmdExest || testKeys || suCmdExecute || giskFile

網(wǎng)絡(luò)情況

這個也是在應(yīng)用當中經(jīng)常會用到的一個屬性,判斷設(shè)備是連接的是wifi,還是連接的是2,3,4,5G網(wǎng)絡(luò),首先通過獲取 NetworkCapabilities來判斷是否連接的是wifi還是移動網(wǎng)絡(luò)

private fun checkNetworkType(): String {
    var net = ""
    val cManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val capabilities: NetworkCapabilities? =
        cManager.getNetworkCapabilities(cManager.activeNetwork)
    capabilities?.let { cb ->
        if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
            net = "WIFI"
        } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
            net = getMobileNetworkType(cManager)
        }
    }
    return "網(wǎng)絡(luò)情況:${net}"
}

當判斷出非wifi網(wǎng)絡(luò)的時候,再通過getMobileNetworkType函數(shù)來得出具體的網(wǎng)絡(luò)類型

private fun getMobileNetworkType(cManager: ConnectivityManager): String {
    val networkInfo = cManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
    if (networkInfo != null) {
        val networkType = networkInfo.subtype
        return when (networkType) {
            TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE -> "2G"
            TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSPA -> "3G"
            TelephonyManager.NETWORK_TYPE_LTE -> "4G"
            TelephonyManager.NETWORK_TYPE_NR -> "5G"
            else -> "UNKNOWN"
        }
    }
    return "UNKNOWN"
}

總結(jié)

文章就到此為止,在拿這些信息的時候,發(fā)現(xiàn)有不少api都已經(jīng)廢棄了,所以還是要注意一下盡量別用廢棄的api去實現(xiàn)功能,防止以后出問題。

以上就是Android相關(guān)硬件信息的獲取方式整理匯總的詳細內(nèi)容,更多關(guān)于Android硬件信息獲取的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android實現(xiàn)拍照截圖功能

    Android實現(xiàn)拍照截圖功能

    這篇文章主要介紹了Android實現(xiàn)拍照截圖功能,簡單介紹了Android實現(xiàn)拍照截圖功能的步驟,供大家參考,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 解決Android 虛擬按鍵遮住了頁面內(nèi)容的問題

    解決Android 虛擬按鍵遮住了頁面內(nèi)容的問題

    今天小編就為大家分享一篇解決Android 虛擬按鍵遮住了頁面內(nèi)容的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • OKHttp使用詳解

    OKHttp使用詳解

    OkHttp 是一套處理 HTTP 網(wǎng)絡(luò)請求的依賴庫,由 Square 公司設(shè)計研發(fā)并開源,目前可以在 Java 和 Kotlin 中使用,這篇文章主要介紹了OKHttp詳解,需要的朋友可以參考下
    2024-01-01
  • 在Android中高效的加載大圖的方法示例

    在Android中高效的加載大圖的方法示例

    本篇文章主要介紹了在Android中高效的加載大圖的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Android如何在root設(shè)備上開啟ViewServer詳解

    Android如何在root設(shè)備上開啟ViewServer詳解

    這篇文章主要給大家介紹了關(guān)于Android中如何在root設(shè)備上開啟ViewServer的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-12-12
  • Android Studio 1.2版安裝設(shè)置圖文教程

    Android Studio 1.2版安裝設(shè)置圖文教程

    這篇文章主要介紹了Android Studio 1.2版安裝設(shè)置圖文教程,本文詳細講解了下載、安裝Android Studio 1.2教程,以及常用設(shè)置詳細圖文教程,需要的朋友可以參考下
    2015-05-05
  • Kotlin Service服務(wù)組件開發(fā)詳解

    Kotlin Service服務(wù)組件開發(fā)詳解

    這幾天分析了一下的啟動過程,于是乎,今天寫一下Service使用; 給我的感覺是它并不復(fù)雜,千萬不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個接著一個,就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口
    2022-12-12
  • Android 中SwipeRefreshLayout與ViewPager滑動事件沖突解決方法

    Android 中SwipeRefreshLayout與ViewPager滑動事件沖突解決方法

    這篇文章主要介紹了Android 中SwipeRefreshLayout與ViewPager滑動事件沖突解決方法的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • android跑馬燈出現(xiàn)重復(fù)跳動以及不滾動問題的解決方法

    android跑馬燈出現(xiàn)重復(fù)跳動以及不滾動問題的解決方法

    這篇文章主要介紹了android跑馬燈出現(xiàn)重復(fù)跳動以及不滾動問題的解決方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Android版的股票行情K線圖開發(fā)

    Android版的股票行情K線圖開發(fā)

    這篇文章主要介紹了Android版的股票行情K線圖開發(fā),感興趣的小伙伴們可以參考一下
    2016-01-01

最新評論