Android适配:判断机型和系统

在Android开发中,我们总是会碰到各种各样的适配问题。如果要解决适配问题,我们必须就要解决,出现问题的是什么机型?出现问题的是什么系统?怎么判断当前机型是不是出问题的机型?这几个问题。这篇文章,就将介绍如何判断机型和系统,介绍目前应该如何解决这些问题。

作者:小墙程序员
链接:https://juejin.cn/post/7241056943388983356

判断指定的机型

在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的机型上测试打印的日志信息:

22869bf40ffa6f1f73faf809c1ec81c9.jpeg

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台设备。如下图所示:

467032f6026a465ffea2acc13533a4e8.jpeg

判断手机的系统

除了机型外,适配过程中我们还需要考虑手机的系统。但是相比于手机机型,手机的系统的判断就没有统一的方式。下面介绍几个常用的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。历史关系如下图所示:

b50fffb05ff3303f921813a98f733b70.jpeg

判断的代码如下。需要注意是对于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。如果你有靠谱的方式,欢迎补充。

关注我获取更多知识或者投稿

5774bc70069940cb20ab148f3149f64e.jpeg

eb4aa5eb66189e6c424fc4ba2ea684a8.jpeg

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android机型是指将应用程序到不同的Android设备上,以确保应用在各种手机和平板电脑上正常运行。过程包括处理不同的屏幕尺寸、分辨率、像素密度、操作系统版本和设备功能的差异。 为了实现Android机型,可以采取以下几个步骤: 1. 使用布局文件:使用XML布局文件来定义应用程序的用户界面,这样可以根据屏幕尺寸和方向自动调整布局。 2. 使用尺寸单位:在布局文件中使用dp或sp等相对单位,而不是像素单位。这样可以确保界面元素在不同密度的屏幕上以相似的比例进行缩放。 3. 处理屏幕尺寸和方向变化:通过重写Activity的onConfigurationChanged()方法,可以在屏幕旋转或尺寸变化时重新布局并应新的屏幕条件。 4. 资源文件:为不同的设备提供不同的资源文件,如图片、图标和字符串等。可以使用不同的文件夹命名规则(如drawable-hdpi、drawable-mdpi等)来存放不同密度的资源文件。 5. 使用功能检测:如果应用使用了某些特定功能(如摄像头、GPS等),可以使用Android提供的API进行功能检测,并在设备不支持时提供当的替代方案。 总之,Android机型是一个综合考虑屏幕尺寸、分辨率、像素密度、操作系统版本和设备功能等因素的过程,通过合理的布局和资源文件管理,确保应用在各种设备上都能良好运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值