Android适配:判断机型和系统
在Android开发中,我们总是会碰到各种各样的适配问题。如果要解决适配问题,我们必须就要解决,出现问题的是什么机型?出现问题的是什么系统?怎么判断当前机型是不是出问题的机型?这几个问题。这篇文章,就将介绍如何判断机型和系统,介绍目前应该如何解决这些问题。
判断指定的机型
在Android里面可以通过 android.os.Build这个类获取相关的机型信息,它的参数如下:(这里以一加的手机为例)
Build.BOARD = lahaina
Build.BOOTLOADER = unknown
Build.BRAND = OnePlus //品牌名
Build.CPU_ABI = arm64-v8a
Build.CPU_ABI2 =
Build.DEVICE = OP5154L1
Build.DISPLAY = MT2110_13.1.0.100(CN01) //设备版本号
Build.FINGERPRINT = OnePlus/MT2110_CH/OP5154L1:13/TP1A.220905.001/R.1038728_2_1:user/release-keys
Build.HARDWARE = qcom
Build.HOST = dg02-pool03-kvm97
Build.ID = TP1A.220905.001
Build.IS_DEBUGGABLE = false
Build.IS_EMULATOR = false
Build.MANUFACTURER = OnePlus //手机制造商
Build.MODEL = MT2110 //手机型号
Build.ODM_SKU = unknown
Build.PERMISSIONS_REVIEW_REQUIRED = true
Build.PRODUCT = MT2110_CH //产品名称
Build.RADIO = unknown
Build.SERIAL = unknown
Build.SKU = unknown
Build.SOC_MANUFACTURER = Qualcomm
Build.SOC_MODEL = SM8350
Build.SUPPORTED_32_BIT_ABIS = [Ljava.lang.String;@fea6460
Build.SUPPORTED_64_BIT_ABIS = [Ljava.lang.String;@3a22d19
Build.SUPPORTED_ABIS = [Ljava.lang.String;@2101de
Build.TAGS = release-keys
Build.TIME = 1683196675000
Build.TYPE = user
Build.UNKNOWN = unknown
Build.USER = root
其中重要的属性已经设置了注释,所有的属性可以看官方文档。在这些属性中,我们一般使用 Build.MANUFACTURER 来判断手机厂商,使用 Build.MODEL 来判断手机的型号。
tips: 如果你是使用kotlin开发,可以使用
android.os.Build::class.java.fields.map { "Build.${it.name} = ${it.get(it.name)}"}.joinToString("\n")
方便的获取所有的属性
上面的获取机型的代码在鸿蒙系统(HarmonyOS)上也同样适用,下面是在华为P50 Pro的机型上测试打印的日志信息:
Build.BOARD = JAD
Build.BOOTLOADER = unknown
Build.BRAND = HUAWEI
Build.CPU_ABI = arm64-v8a
Build.CPU_ABI2 =
Build.DEVICE = HWJAD
Build.DISPLAY = JAD-AL50 2.0.0.225(C00E220R3P4)
Build.FINGERPRINT = HUAWEI/JAD-AL50/HWJAD:10/HUAWEIJAD-AL50/102.0.0.225C00:user/release-keys
Build.FINGERPRINTEX = HUAWEI/JAD-AL50/HWJAD:10/HUAWEIJAD-AL50/102.0.0.225C00:user/release-keys
Build.HARDWARE = kirin9000
Build.HIDE_PRODUCT_INFO = false
Build.HOST = cn-east-hcd-4a-d3a4cb6341634865598924-6cc66dddcd-dcg9d
Build.HWFINGERPRINT = ///JAD-LGRP5-CHN 2.0.0.225/JAD-AL50-CUST 2.0.0.220(C00)/JAD-AL50-PRELOAD 2.0.0.4(C00R3)//
Build.ID = HUAWEIJAD-AL50
Build.IS_CONTAINER = false
Build.IS_DEBUGGABLE = false
Build.IS_EMULATOR = false
Build.IS_ENG = false
Build.IS_TREBLE_ENABLED = true
Build.IS_USER = true
Build.IS_USERDEBUG = false
Build.MANUFACTURER = HUAWEI
Build.MODEL = JAD-AL50
Build.NO_HOTA = false
Build.PERMISSIONS_REVIEW_REQUIRED = true
Build.PRODUCT = JAD-AL50
Build.RADIO = unknown
Build.SERIAL = unknown
Build.SUPPORTED_32_BIT_ABIS = [Ljava.lang.String;@a90e093
Build.SUPPORTED_64_BIT_ABIS = [Ljava.lang.String;@8ce98d0
Build.SUPPORTED_ABIS = [Ljava.lang.String;@366a0c9
Build.TAGS = release-keys
Build.TIME = 1634865882000
Build.TYPE = user
Build.UNKNOWN = unknown
综上,判断手机厂商的代码如下:
//是否是荣耀设备
fun isHonorDevice() = Build.MANUFACTURER.equals("HONOR", ignoreCase = true)
//是否是小米设备
fun isXiaomiDevice() = Build.MANUFACTURER.equals("Xiaomi", ignoreCase = true)
//是否是oppo设备
//realme 是oppo的海外品牌后面脱离了;一加是oppo的独立运营品牌。因此判断
//它们是需要单独判断
fun isOppoDevice() = Build.MANUFACTURER.equals("OPPO", ignoreCase = true)
//是否是一加手机
fun isOnePlusDevice() = Build.MANUFACTURER.equals("OnePlus", ignoreCase = true)
//是否是realme手机
fun isRealmeDevice() = Build.MANUFACTURER.equals("realme", ignoreCase = true)
//是否是vivo设备
fun isVivoDevice() = Build.MANUFACTURER.equals("vivo", ignoreCase = true)
//是否是华为设备
fun isHuaweiDevice() = Build.MANUFACTURER.equals("HUAWEI", ignoreCase = true)
需要判断指定的型号的代码则为:
//判断是否是小米12s的机型
fun isXiaomi12S() = isXiaomiDevice() && Build.MODEL.contains("2206123SC") //xiaomi 12s
如果你不知道对应机型的型号,可以看基于谷歌维护的表格,支持超过27,000台设备。如下图所示:
判断手机的系统
除了机型外,适配过程中我们还需要考虑手机的系统。但是相比于手机机型,手机的系统的判断就没有统一的方式。下面介绍几个常用的os的判断
● 鸿蒙
private static final String HARMONY_OS = "harmony";
/**
* check the system is harmony os
*
* @return true if it is harmony os
*/
public static boolean isHarmonyOS() {
try {
Class clz = Class.forName("com.huawei.system.BuildEx");
Method method = clz.getMethod("getOsBrand");
return HARMONY_OS.equals(method.invoke(clz));
} catch (ClassNotFoundException e) {
Log.e(TAG, "occured ClassNotFoundException");
} catch (NoSuchMethodException e) {
Log.e(TAG, "occured NoSuchMethodException");
} catch (Exception e) {
Log.e(TAG, "occur other problem");
}
return false;
}
● Miui
fun checkIsMiui() = !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.name"))
private fun getSystemProperty(propName: String): String? {
val line: String
var input: BufferedReader? = null
try {
val p = Runtime.getRuntime().exec("getprop $propName")
input = BufferedReader(InputStreamReader(p.inputStream), 1024)
line = input.readLine()
input.close()
} catch (ex: IOException) {
Log.i(TAG, "Unable to read sysprop $propName", ex)
return null
} finally {
if (input != null) {
try {
input.close()
} catch (e: IOException) {
Log.i(TAG, "Exception while closing InputStream", e)
}
}
}
return line
}
● Emui 或者 Magic UI
Emui是2018之前的荣耀机型的os,18年之后是 Magic UI。历史关系如下图所示:
判断的代码如下。需要注意是对于Android 12以下的机型,官方文档并没有给出对于的方案,下面代码的方式是从网上找的,目前测试了4台不同的机型,均可正在判断。
fun checkIsEmuiOrMagicUI(): Boolean {
return if (Build.VERSION.SDK_INT >= 31) {
//官方方案,但是只适用于api31以上(Android 12)
try {
val clazz = Class.forName("com.hihonor.android.os.Build")
Log.d(TAG, "clazz = " + clazz)
true
}catch (e: ClassNotFoundException) {
Log.d(TAG, "no find class")
e.printStackTrace()
false
}
} else {
//网上方案,测试了 荣耀畅玩8C
// 荣耀20s、荣耀x40 、荣耀v30 pro 四台机型,均可正常判断
!TextUtils.isEmpty(getSystemProperty("ro.build.version.emui"))
}
}
● Color Os
下面是网上判断是否是Oppo的ColorOs的代码。经测试,在 OPPO k10 、 oppo findx5 pro、 oneplus 9RT 手机上都是返回 false,只有在 realme Q3 pro 机型上才返回了 true。
//这段代码是错的
fun checkIsColorOs() = !TextUtils.isEmpty(getSystemProperty("ro.build.version.opporom"))
从测试结果可以看出上面这段代码是错的,但是在 ColorOs 的官网上,没有找到如何判断ColorOs的代码。这种情况下,有几种方案:
1. 判断手机制造商,即 Build.MANUFACTURER 如果为 oneplus、oppo、realme就认为它是ColorOs
2. 根据系统应用的包名判断,即判断是否带有 com.coloros.* 的系统应用,如果有,就认为它是ColorOs
这几种方案都有很多问题,暂时没有找到更好的解决方法。
● Origin Os
//网上代码,在 IQOQ Neo5、vivo Y50、 vivo x70三种机型上
//都可以正常判断
fun checkIsOriginOs() = !TextUtils.isEmpty(getSystemProperty("ro.vivo.os.version"))
总结
对于手机厂商和机型,我们可以通过Android原生的 android.os.Build 类来判断。使用 Build.MANUFACTURER 来判断手机厂商,使用 Build.MODEL 来判断手机的型号。如果是不知道的型号,还可以尝试在谷歌维护的手机机型表格中查询。
但是对于厂商的系统,就没有统一的判断方法了。部分厂商有官方提供的判断方式,如Miui、Magic UI;部分厂商暂时没有找到相关的内容。这种情况下,只能通过网上的方式判断,但是部分内容也不靠谱,如判断Oppo的ColorOs。如果你有靠谱的方式,欢迎补充。
参考
来源:juejin.cn/post/7241056943388983356