随着Android 版本的更新,获取手机序列号的方式也有所不同。最近咋工作中看到了,查阅资料在这里总结下目前。

一、获取序列号

public class MainActivity extends AppCompatActivity {    private static final String TAG = MainActivity.class.getSimpleName();    private static final int CODE_READ_PHONE_STATE = 0x11;    private String serialNumber = "UNKNOWN";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        getSerialNumber();    }    @RequiresApi(api = Build.VERSION_CODES.O)    public void checkPermission() {        if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {            requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, CODE_READ_PHONE_STATE);        } else {            serialNumber = Build.getSerial();        }    }    @RequiresApi(api = Build.VERSION_CODES.O)    @SuppressLint("MissingPermission")    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        if (requestCode == CODE_READ_PHONE_STATE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {            serialNumber = Build.getSerial();        } else {            Log.i(TAG, "you deny the permission:READ_PHONE_STATE");        }    }    @SuppressLint("HardwareIds")    public String getSerialNumber() {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {// android Q(安卓10)             // TODO use yourself style        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // android O_MR1(安卓8.1)、android P(安卓 9)            checkPermission();        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){// android O(安卓 8.0)            this.serialNumber = Build.SERIAL;        }else {//below android 8.0            try {             // 方式1:执行adb 命令获得                Runtime runtime = Runtime.getRuntime();                Process process = null;                process = runtime.exec("getprop ro.serialno");                InputStream is = process.getInputStream();                InputStreamReader isr = new InputStreamReader(is);                BufferedReader br = new BufferedReader(isr);                this.serialNumber = br.readLine();                // 方式2:反射获得(不推荐使用)//                Class<?> c = Class.forName("android.os.SystemProperties");//                Method get = c.getMethod("get", String.class);//                serialNumber = (String) get.invoke(c, "ro.serialno");//                Log.i(TAG, "  sdk version low android O ,reflect get" + serialNumber);            } catch (IOException e) {                e.printStackTrace();            }        }        return serialNumber;    }}

二、测试过程及其结论

1、有关Build.SERIAL字段获取方式

测试结论:
1、安卓8.0及8.0以下可以获得结果。
2、安卓8.1及其以上返回UNKNOWN
文档说明:如下图。
3、8.0时废弃啦,8.0及其以上版本建议使用getSerial()方法代替。


个人结论

8.0还可以用这个方式获取,因为getSerial()方式需要“read phone state” 权限,而读取手机权限时总要去让用户决定,相对来说有点限制。

2、有关Build.getSerial()获取方式

(1)测试结论

1、安卓10(api 29)手机上直接崩溃(api28以上)
2、安卓8.0(api 26)、安卓9(api 28)上可以获得,需要“read phone state” 权限,否则崩溃
小结论:Build.getSerial()是安卓8.0-9.0上Build.SERIAL废弃后的替代方案。

(2)Build.getSerial()的官方api参考

1、Requires Permission: READ_PRIVILEGED_PHONE_STATE2、If the calling app's target SDK is API level 28 or lower and the app has the     READ_PHONE_STATE permission then {@link Build#UNKNOWN} is returned.3、If the calling app's target SDK is API level 28 or lower and the app does not have     the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or     higher, then a SecurityException is thrown

1、需要READ_PRIVILEGED_PHONE_STATE(READ_PHONE_STATE也行)
2、如果调用应用程序的目标SDK是API级别28或更低,并且应用程序具有READ_PHONE_STATE权限,那么返回#UNKNOWN
3、如果调用应用程序的目标SDK是API级别28或更低,且应用程序没有READ_PHONE_STATE权限,或者如果调用应用程序的目标API级别29或更高,则抛出SecurityException。
ps:总感觉官方这段注释写的有点怪怪的(参考上述个人测试结论)

3、有关8.0以下获取方式

(1)Build.SERIAL获取

这种获取方式支持到8.0及其以下,但会8.0以下网上文章好多都使用反射获得,这里大家合理选择吧!!!

(2)adb 命令或者反射获取测试

1、二者在8.0(>=8.0)版本上获取值为空,8.0以下可以获得
2、不建议使用反射方式获取。(如下图)

4、有关10.0及其更高版本的替代方案

这里建议自己实现:
实现参考如下:
1、官方建议
2、前人实践

The end

给出了自己总结的一种方案,,,,,溜溜球。

更多相关文章

  1. ConstraintLayout 使用可视化的方式来编写Android应用程序的界面
  2. Android(安卓)studio 3.1.3 无法获取pom文件
  3. Android添加快捷方式(Shortcut)到手机桌面
  4. Android布局之LinearLayout
  5. View常见XML属性及相关方法
  6. Android(安卓)获取手机唯一标识(仅限IMEI)
  7. JS与Android交互之html页面跳转到Android(安卓)Activity
  8. Android存储权限
  9. Android(安卓)控件之DatePicker,TimePicker,Calender

随机推荐

  1. Android开发指南中文版(二)Application Fun
  2. Android线性LinearLayout布局xml属性介绍
  3. Flutter学习笔记(30)--Android原生与Flutte
  4. android adb命令
  5. Android之——史上最简单自定义开关按钮
  6. Android中数据存储——SharedPreferences
  7. 安卓知道多少
  8. Android(安卓)编译C模块
  9. Android(安卓)Wear手表蓝牙连接Android(
  10. android常用命令