下面我将从易到难,介绍几种主流的方法,并提供相应的代码示例。

(图片来源网络,侵删)
使用 OpenGL ES API (推荐,最常用)
这是最可靠、最官方的方法,我们可以通过 EGL14 (EGL 1.4) 和 GL10 (OpenGL ES 1.0) 的 API 来查询渲染器信息,虽然使用的是旧版 API,但它们在所有支持 OpenGL ES 的设备上都可用,并且返回的字符串信息非常标准。
核心思路:
- 获取
EGLDisplay对象,这是与显示系统的连接。 - 获取当前上下文所使用的
EGLContext。 - 使用
eglQueryString()函数查询EGL_EXTENSIONS字符串。 - 从扩展字符串中解析出 GPU 的供应商和渲染器信息。
代码示例:
import android.opengl.GLSurfaceView;
import android.util.Log;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
public class GpuInfoUtil {
private static final String TAG = "GpuInfoUtil";
/**
* 通过 OpenGL ES API 获取 GPU 信息
* @param glSurfaceView 传入一个 GLSurfaceView 实例,用于获取 EGL 上下文
* @return 包含 GPU 信息的字符串,"Qualcomm, Adreno (TM) 640"
*/
public static String getGpuInfoViaOpenGL(GLSurfaceView glSurfaceView) {
if (glSurfaceView == null || glSurfaceView.getEGLContext() == null) {
Log.e(TAG, "GLSurfaceView or its EGLContext is null.");
return "Unknown";
}
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (display == EGL10.EGL_NO_DISPLAY) {
Log.e(TAG, "Unable to get EGL display.");
return "Unknown";
}
EGLContext context = glSurfaceView.getEGLContext();
String glExtensions = egl.eglQueryString(display, EGL10.EGL_EXTENSIONS);
if (glExtensions == null) {
Log.e(TAG, "Unable to get EGL extensions string.");
return "Unknown";
}
// 解析 GPU 供应商和渲染器
String vendor = parseGpuInfo(glExtensions, "EGL_VENDOR");
String renderer = parseGpuInfo(glExtensions, "EGL_RENDERER");
return vendor + ", " + renderer;
}
/**
* 从 EGL 扩展字符串中解析特定的 GPU 信息
* @param extensions EGL_EXTENSIONS 字符串
* @param prefix 要查找的前缀,如 "EGL_VENDOR" 或 "EGL_RENDERER"
* @return 对应的 GPU 信息
*/
private static String parseGpuInfo(String extensions, String prefix) {
int index = extensions.indexOf(prefix);
if (index == -1) {
return "Unknown";
}
// 找到前缀后,移动到实际内容的起始位置
int start = index + prefix.length();
// 通常信息在引号内,所以我们寻找引号
int quoteStart = extensions.indexOf('"', start);
if (quoteStart == -1) {
// 如果没有引号,就取到下一个空格
int spaceIndex = extensions.indexOf(' ', start);
if (spaceIndex == -1) {
return extensions.substring(start).trim();
}
return extensions.substring(start, spaceIndex).trim();
}
int quoteEnd = extensions.indexOf('"', quoteStart + 1);
if (quoteEnd == -1) {
return "Unknown";
}
return extensions.substring(quoteStart + 1, quoteEnd).trim();
}
}
如何使用:
你可以在你的 Activity 或 Fragment 中,当 GLSurfaceView 初始化完成后调用这个方法。

(图片来源网络,侵删)
// 在你的 Activity 或 Fragment 中
GLSurfaceView glView = findViewById(R.id.gl_surface_view);
// ... 初始化 glView ...
// 在渲染器设置好后,或者在 onResume 中调用
String gpuInfo = GpuInfoUtil.getGpuInfoViaOpenGL(glView);
Log.d("GPU Info", gpuInfo); // 输出类似: "Qualcomm, Adreno (TM) 640"
读取 /proc/version 或 /proc/cpuinfo 文件 (间接方法)
在某些设备上,GPU 信息可能会被包含在系统文件中,这种方法不如第一种可靠,因为不同厂商的设备文件内容可能不同,但它不需要 OpenGL 环境,在某些非图形应用中可能有用。
核心思路:
读取 /proc/version 或 /proc/cpuinfo 文件,并尝试用正则表达式匹配出 GPU 相关的关键字(如 "Adreno", "Mali", "NVIDIA", "PowerVR")。
代码示例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SystemInfoUtil {
private static final String TAG = "SystemInfoUtil";
/**
* 通过读取系统文件获取 GPU 信息
* @return 匹配到的 GPU 关键字,如果没有则返回 "Unknown"
*/
public static String getGpuInfoFromFile() {
String gpuInfo = "Unknown";
try {
// 首先尝试从 /proc/version 读取
gpuInfo = readFromFileAndFindGpu("/proc/version");
if (!"Unknown".equals(gpuInfo)) {
return gpuInfo;
}
// /proc/version 没有找到,再尝试 /proc/cpuinfo
gpuInfo = readFromFileAndFindGpu("/proc/cpuinfo");
return gpuInfo;
} catch (IOException e) {
Log.e(TAG, "Error reading system files", e);
}
return gpuInfo;
}
private static String readFromFileAndFindGpu(String filePath) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
// 使用正则表达式匹配常见的 GPU 关键字
// 这个正则表达式可以匹配 Adreno, Mali, NVIDIA, PowerVR 等品牌
Pattern pattern = Pattern.compile("(Adreno|Mali|NVIDIA|PowerVR|GeForce|Tegra)", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
return matcher.group(1);
}
}
}
return "Unknown";
}
}
注意:

(图片来源网络,侵删)
- 这种方法获取到的信息通常只是 GPU 的品牌,而不是具体的型号(如 "Adreno 640")。
- 它的可靠性远低于方法一,仅作为备选方案。
使用 android.os.Build 类 (最简单,但信息有限)
这个类主要提供设备硬件和软件的顶层信息,不包含详细的 GPU 型号,但对于某些特定用途(如判断是否为模拟器)很有用。
核心思路:
检查 Build.FINGERPRINT 或 Build.MODEL 中是否包含 GPU 相关的关键词。
代码示例:
import android.os.Build;
public class BuildInfoUtil {
public static String getGpuInfoFromBuild() {
// 检查设备指纹,有时会包含 GPU 信息
String fingerprint = Build.FINGERPRINT.toLowerCase();
if (fingerprint.contains("adreno")) {
return "Qualcomm Adreno (from fingerprint)";
} else if (fingerprint.contains("mali")) {
return "ARM Mali (from fingerprint)";
}
// 检查设备型号
String model = Build.MODEL.toLowerCase();
if (model.contains("pixel")) {
// Pixel 设备通常使用 Adreno GPU
return "Google Adreno (from model)";
}
return "Unknown (from Build)";
}
}
注意: 这种方法非常不可靠,信息非常有限,仅用于非常粗略的判断。
总结与最佳实践
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| OpenGL ES API | 最准确、最可靠、信息最丰富(能获取到具体型号) | 需要一个 GLSurfaceView 实例或 OpenGL 环境 |
游戏开发、性能分析、需要精确 GPU 信息的场景 |
| 读取系统文件 | 不需要 OpenGL 环境,可在非图形应用中使用 | 不可靠,信息不完整(通常只有品牌),依赖厂商实现 | 辅助手段,或在没有 OpenGL 环境下的快速判断 |
android.os.Build |
最简单,无需额外依赖 | 信息极其有限且不可靠 | 仅用于判断是否为模拟器等非常粗略的场景 |
推荐的工作流程:
- 首选方法一 (
OpenGL ES API):如果你的应用是图形密集型的(如游戏、3D应用),或者你需要最准确的 GPU 信息,这是唯一的选择。 - 备用方法二 (读取文件):如果你的应用不是图形应用,但又想获取 GPU 信息,可以尝试这个方法作为备选,你可以结合方法一和方法二,如果方法一失败(在没有 OpenGL 环境的 Service 中),则回退到方法二。
- 避免使用方法三:除非你只是想做一个非常粗略的、非关键性的检查,否则不要依赖
Build类来获取 GPU 信息。
对于绝大多数开发者来说,掌握和使用第一种方法 (OpenGL ES API) 就足够了,它提供了最准确、最标准化的信息。
