Build类包含了许多手机信息,如手机设备名,芯片名,制程商的名字,model,android软件版本,SDK,fingerprint等等重要信息。

一个关于Build的Demo

import android.os.Build;


private void init() {
    // TODO Auto-generated method stub
    Log.i(TAG, "Build.ID:"+Build.ID);
    Log.i(TAG, "Build.DISPLAY:"+Build.DISPLAY);
    Log.i(TAG, "Build.PRODUCT:"+Build.PRODUCT);
    Log.i(TAG, "Build.DEVICE:"+Build.DEVICE);
    Log.i(TAG, "Build.BOARD:"+Build.BOARD);
    Log.i(TAG, "Build.MANUFACTURER:"+Build.MANUFACTURER);
    Log.i(TAG, "Build.BRAND:"+Build.BRAND);
    Log.i(TAG, "Build.MODEL:"+Build.MODEL);
    Log.i(TAG, "Build.BOOTLOADER:"+Build.BOOTLOADER);
    Log.i(TAG, "Build.HARDWARE:"+Build.HARDWARE);
    Log.i(TAG, "Build.SERIAL:"+Build.SERIAL);
    //Log.i(TAG, "Build.SUPPORTED_ABIS:"+Build.SUPPORTED_ABIS);
    //Log.i(TAG, "Build.SUPPORTED_32_BIT_ABIS:"+Build.SUPPORTED_32_BIT_ABIS);
    //Log.i(TAG, "Build.SUPPORTED_64_BIT_ABIS:"+Build.SUPPORTED_64_BIT_ABIS);
    Log.i(TAG, "Build.VERSION.INCREMENTAL:"+Build.VERSION.INCREMENTAL);
    Log.i(TAG, "Build.VERSION.RELEASE:"+Build.VERSION.RELEASE);
    Log.i(TAG, "Build.VERSION.SDK:"+Build.VERSION.SDK);
    Log.i(TAG, "Build.VERSION.SDK_INT:"+Build.VERSION.SDK_INT);
    Log.i(TAG, "Build.VERSION.CODENAME:"+Build.VERSION.CODENAME);
    Log.i(TAG, "Build.TYPE:"+Build.TYPE);
    Log.i(TAG, "Build.TAGS:"+Build.TAGS);
    Log.i(TAG, "Build.FINGERPRINT:"+Build.FINGERPRINT);
    Log.i(TAG, "Build.TIME:"+Build.TIME);
    Log.i(TAG, "Build.USER:"+Build.USER);
    Log.i(TAG, "Build.HOST:"+Build.HOST);
    //Log.i(TAG, "Build.IS_DEBUGGABLE:"+Build.IS_DEBUGGABLE);
}

Log信息如下:

11-27 08:02:22.975: I/MainActivity(13256): Build.ID:LRX22G
11-27 08:02:22.975: I/MainActivity(13256): Build.DISPLAY:LRX22G release-keys
11-27 08:02:22.975: I/MainActivity(13256): Build.PRODUCT:l9010_cla
11-27 08:02:22.975: I/MainActivity(13256): Build.DEVICE:l9010_cla
11-27 08:02:22.975: I/MainActivity(13256): Build.BOARD:msm8916
11-27 08:02:22.975: I/MainActivity(13256): Build.MANUFACTURER:Lanix
11-27 08:02:22.975: I/MainActivity(13256): Build.BRAND:qcom
11-27 08:02:22.975: I/MainActivity(13256): Build.MODEL:Ilium L950
11-27 08:02:22.976: I/MainActivity(13256): Build.BOOTLOADER:unknown
11-27 08:02:22.976: I/MainActivity(13256): Build.HARDWARE:qcom
11-27 08:02:22.976: I/MainActivity(13256): Build.SERIAL:1ca7811b
11-27 08:02:22.976: I/MainActivity(13256): Build.VERSION.INCREMENTAL:eng.android.20151126
11-27 08:02:22.976: I/MainActivity(13256): Build.VERSION.RELEASE:5.0.2
11-27 08:02:22.976: I/MainActivity(13256): Build.VERSION.SDK:21
11-27 08:02:22.976: I/MainActivity(13256): Build.VERSION.SDK_INT:21
11-27 08:02:22.976: I/MainActivity(13256): Build.VERSION.CODENAME:REL
11-27 08:02:22.976: I/MainActivity(13256): Build.TYPE:user
11-27 08:02:22.976: I/MainActivity(13256): Build.TAGS:release-keys
11-27 08:02:22.976: I/MainActivity(13256): Build.FINGERPRINT:LANIX/Ilium_L950/Ilium_L950:5.0.2/LRX22G/eng.android.20150828:user/release-keys
11-27 08:02:22.976: I/MainActivity(13256): Build.TIME:1448503027000
11-27 08:02:22.976: I/MainActivity(13256): Build.USER:android
11-27 08:02:22.976: I/MainActivity(13256): Build.HOST:C208

Build源码分析

基本属性

我们打开Build源码(./frameworks/base/core/java/android/os/Build.java),大概的看一下源码:

public class Build {
    private static final String TAG = "Build";

    /** Value used for when a build property is unknown. */
    public static final String UNKNOWN = "unknown";

    /** Either a changelist number, or a label like "M4-rc20". */
    public static final String ID = getString("ro.build.id");

    /** A build ID string meant for displaying to the user */
    public static final String DISPLAY = getString("ro.build.display.id");

    /** The name of the overall product. */
    public static final String PRODUCT = getString("ro.product.name");

    /** The name of the industrial design. */
    public static final String DEVICE = getString("ro.product.device");

    /** The name of the underlying board, like "goldfish". */
    public static final String BOARD = getString("ro.product.board");

.............

Build类中主要是一些成员属性,这些属性看的眼熟不,对,如果你接触过手机的属性的话,那么你就会明白,这就是读取的手机属性值。

下面是我列的一个表格:

成员属性

手机属性名

手机属性值

ID

ro.build.id

LRX22G

DISPLAY

ro.build.display.id

LRX22G release-keys

PRODUCT

ro.product.name

l9010_cla

DEVICE

ro.product.device

l9010_cla

BOARD

ro.product.board

msm8916

MANUFACTURER

ro.product.manufacturer

Lanix

BRAND

ro.product.brand

qcom

MODEL

ro.product.model

Ilium L950

BOOTLOADER

ro.bootloader

unknown

HARDWARE

ro.hardware

qcom

SERIAL

ro.serialno

1ca7811b

SUPPORTED_ABIS

ro.product.cpu.abilist

armeabi-v7a,armeabi

SUPPORTED_32_BIT_ABIS

ro.product.cpu.abilist32

armeabi-v7a,armeabi

SUPPORTED_64_BIT_ABIS

ro.product.cpu.abilist64

INCREMENTAL

ro.build.version.incremental

eng.android.20151126

RELEASE

ro.build.version.release

5.0.2

SDK

ro.build.version.sdk

21

SDK_INT

ro.build.version.sdk

21

CODENAME

ro.build.version.codename

REL

TYPE

ro.build.type

user

TAGS

ro.build.tags

release-keys

FINGERPRINT

ro.build.fingerprint

LANIX/Ilium_L950/Ilium_L950:5.0.2/LRX22G/eng.android.20150828:user/release-keys

TIME

ro.build.date.utc

1448503027

USER

ro.build.user

android

HOST

ro.build.host

C208

IS_DEBUGGABLE

ro.debuggable

1

关于版本的成员属性

VERSION_CODES:
        /**
         * October 2008: The original, first, version of Android.  Yay!
         */
        public static final int BASE = 1;

        /**
         * February 2009: First Android update, officially called 1.1.
         */
        public static final int BASE_1_1 = 2;

        /**
         * May 2009: Android 1.5.
         */
        public static final int CUPCAKE = 3;

        /**
         * September 2009: Android 1.6. 
         */
        public static final int DONUT = 4;

     ........................
     ........................

        /**
         * Android 4.4W: KitKat for watches, snacks on the run.
         */
        public static final int KITKAT_WATCH = 20;

        /**
         * Temporary until we completely switch to {@link #LOLLIPOP}.
         * @hide
         */
        public static final int L = 21;

        /**
         * Lollipop.  A flat one with beautiful shadows.  But still tasty.
         */
        public static final int LOLLIPOP = 21;

下面这个列表是关于软件版本号的表格:

VERSION_CODES

成员属性

软件版本号

APK值

BASE

1.0

1

BASE_1_1

1.1

2

CUPCAKE

1.5

3

DONUT

1.6

4

ECLAIR

2.0

5

EECLAIR_0_1

2.0.1

6

ECLAIR_MR1

2.1

7

FROYO

2.2

8

GINGERBREAD

2.3

9

GINGERBREAD_MR1

2.3.3

10

HONEYCOMB

3.0

11

HONEYCOMB_MR1

3.1

12

HONEYCOMB_MR2

3.2

13

ICE_CREAM_SANDWICH

4.0

14

ICE_CREAM_SANDWICH_MR1

4.0.3

15

JELLY_BEAN

4.1

16

JELLY_BEAN_MR1

4.2

17

JELLY_BEAN_MR2

4.3

18

KITKAT

4.4

19

KITKAT_WATCH

4.4W

20

L

5.0

21

LOLLIPOP

5.0

21

关于fingerprint

先看代码:

private static String deriveFingerprint() {
        String finger = SystemProperties.get("ro.build.fingerprint");
        if (TextUtils.isEmpty(finger)) {
            finger = getString("ro.product.brand") + '/' +
                    getString("ro.product.name") + '/' +
                    getString("ro.product.device") + ':' +
                    getString("ro.build.version.release") + '/' +
                    getString("ro.build.id") + '/' +
                    getString("ro.build.version.incremental") + ':' +
                    getString("ro.build.type") + '/' +
                    getString("ro.build.tags");
        }
        return finger;
}

代码非常明白的告诉我们,fingerprint有二种方式获取,
一种是直接读取:ro.build.fingerprint,
如果读取的ro.build.fingerprint信息为空,那么我们会使用拼接的方式获取fingerprint:
拼接的方式如下:

ro.product.brand+ro.product.name+ro.product.device+ro.build.version.release+ro.build.id+ro.build.version.incremental+ro.build.type+ro.build.tags

拼接结果如下:

qcom+l9010_cla+l9010_cla+5.0.2+LRX22G+eng.android.20151126+user+release-keys

我们直接读取的如果:

LANIX/Ilium_L950/Ilium_L950:5.0.2/LRX22G/eng.android.20150828:user/release-keys

如果,这二种方式得到的fingerprint不一致,在GMS认证时CTS测试会有一个fingerprint的测试fail项,我们只要对应此拼接的方式来修改对应的属性值,就可以把此Fail项解决。