You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android API 30中HardwarePropertiesManager报错及CPU信息获取方案咨询

Android 11(API 30)下获取CPU温度、使用率及内存信息的替代方案

原代码使用HardwarePropertiesManager触发SecurityException的原因是:从Android 10(API 29)开始,该类的温度查询方法就被严格限制,仅允许设备所有者、持有系统签名级DEVICE_POWER权限的应用,或是当前VrListener调用,普通应用无法直接使用。以下是普通应用可采用的替代方案:


一、获取CPU使用率

通过读取Linux内核提供的/proc/stat文件计算CPU使用率,这是Android平台通用的方式:

public static float getCpuUsage() {
    try {
        RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
        String load = reader.readLine();
        String[] toks = load.split(" ");

        long idle1 = Long.parseLong(toks[5]);
        long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

        // 间隔360ms读取第二次数据,确保差值有效
        Thread.sleep(360);

        reader.seek(0);
        load = reader.readLine();
        reader.close();

        toks = load.split(" ");
        long idle2 = Long.parseLong(toks[5]);
        long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

        // 计算这段时间内的CPU使用率
        return (float) (cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1)) * 100;
    } catch (IOException | InterruptedException ex) {
        ex.printStackTrace();
    }
    return 0;
}

说明:/proc/stat存储的是系统启动以来的CPU累计运行时间,必须通过两次读取的差值计算实时使用率。


二、获取CPU温度

普通应用无法通过系统API直接获取CPU温度,可尝试读取sysfs下的温度节点(不同厂商设备路径可能不同):

public static float getCpuTemperature() {
    // 常见的CPU温度节点路径,需根据设备适配
    String[] possiblePaths = {
        "/sys/class/thermal/thermal_zone0/temp",
        "/sys/class/thermal/thermal_zone1/temp",
        "/sys/devices/virtual/thermal/thermal_zone0/temp"
    };

    for (String path : possiblePaths) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String tempStr = reader.readLine();
            reader.close();
            if (tempStr != null) {
                // 读取值为毫摄氏度,转换为摄氏度
                return Float.parseFloat(tempStr) / 1000.0f;
            }
        } catch (IOException e) {
            // 路径不存在则尝试下一个
            continue;
        }
    }
    // 所有路径读取失败时返回-1
    return -1;
}

说明:部分厂商可能限制普通应用读取这些节点的权限,此时无法获取CPU温度。


三、获取内存信息

使用系统提供的ActivityManager和MemoryInfo API,普通应用可直接调用:

public static void getMemoryInfo(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);

    long totalMemory = memoryInfo.totalMem;
    long availableMemory = memoryInfo.availMem;
    float memoryUsage = (1 - (float) availableMemory / totalMemory) * 100;

    // 转换为MB单位便于阅读
    float totalMemMB = totalMemory / (1024 * 1024);
    float availableMemMB = availableMemory / (1024 * 1024);

    Log.d("MemoryInfo", "总内存:" + String.format("%.2f", totalMemMB) + " MB");
    Log.d("MemoryInfo", "可用内存:" + String.format("%.2f", availableMemMB) + " MB");
    Log.d("MemoryInfo", "内存使用率:" + String.format("%.2f", memoryUsage) + "%");
}

四、获取CPU核心信息

读取/proc/cpuinfo文件获取核心数、型号等信息:

// 获取CPU核心数
public static int getCpuCoreCount() {
    try {
        BufferedReader reader = new BufferedReader(new FileReader("/proc/cpuinfo"));
        String line;
        int coreCount = 0;
        while ((line = reader.readLine()) != null) {
            if (line.startsWith("processor")) {
                coreCount++;
            }
        }
        reader.close();
        return coreCount;
    } catch (IOException e) {
        e.printStackTrace();
        // 读取失败时返回Runtime统计的可用核心数
        return Runtime.getRuntime().availableProcessors();
    }
}

// 获取CPU型号
public static String getCpuModel() {
    try {
        BufferedReader reader = new BufferedReader(new FileReader("/proc/cpuinfo"));
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.startsWith("model name")) {
                return line.split(":")[1].trim();
            }
        }
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "Unknown";
}

内容的提问来源于stack exchange,提问作者BePositve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:27:20