七、Android 唯一标识符

唯一标识符可用于一系列任务,从允许用户设置广告偏好、唯一标识用户,到标识特定设备。当涉及到由 Android 权限和 Google Play 开发者政策强制执行的唯一标识符的使用时,也存在强烈的隐私问题。

为了解决用户隐私问题,从 Android 10 (API 级别 29)开始,在如何从 Android 应用中访问硬件唯一标识符方面有了很大的变化。也就是说,应用必须是设备或配置文件的所有者,拥有特殊的运营商权限,或拥有READ_PRIVILEGED_PHONE_STATE特权权限,才能访问不可重置的设备标识符。READ_PRIVILEGED_PHONE_STATE permission仅适用于使用设备平台(系统应用)密钥 1 签名的应用。

Google Play 广告 ID

截至 Android KitKat (API level 4.4),Google Play 广告 ID 2 可用于唯一识别设备用户。当在设备上可用时,出于广告目的使用任何其他设备唯一标识符都是违反 Google Play 开发者计划政策的。广告 ID 对最终用户的好处是它既可重置又可用于定制个性化广告。返回的 ID 的一个例子是9fdbfa02-7f28-422e-944e-f02393a9360e的字符串表示。由于广告 ID 由 Google Play 服务 API 提供,这意味着它只能在具有 Google Play 服务的设备上使用。

可以通过将以下库路径添加到 build.gradle 文件的 dependencies 标签来使用广告 ID:

implementation 'com.google.android.gms:play-services-ads:7.0.0'

检索广告 ID(这不能在主线程上完成——这个例子使用了一个 AsyncTask 详见 第 9 章:

void getAdvertisingID(final Context context){

    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            Info adInfo = null;
            try {
                adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (GooglePlayServicesNotAvailableException e) {
                e.printStackTrace();
            } catch (GooglePlayServicesRepairableException e) {
                e.printStackTrace();
            }
            String adId = adInfo != null ? adInfo.getId() : null;

            Log.v("Advertising ID",adId);

        }
    });
}

Android ID(安全设置 Android ID–SSAID)

这是一个唯一的 64 位数字(例如,ce79870fa5cbfb56),是 Android 在广告之外的活动中识别设备用户的首选方法。这个唯一标识符在所有版本的 Android 上都可用,不需要任何额外的权限,并且作为设备出厂重置的一部分被重置。

访问 安卓 ID :

Log.v("Android ID",Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID));

SIM 序列号

SIM 序列号用于国际识别,通常分为 19 位数字 3 。这可以分解为两位数字的电信 ID、两位数字的国家代码、两位数字的网络代码、四位数字的生产月份和年份、两位数字的交换机配置代码、六位数字的 SIM 号码和一个校验位。

SIM 序列号在 Android Pie (API 级别 28)及以下版本的 Android 上可用,在 Android 10 及以上版本中受限于READ_PRIVILEGED_PHONE_STATE权限。使用 Android 10 之前的 SIM 序列号需要READ_PHONE_STATE运行时权限。

检索 SIM 序列号:

TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
Log.v("SIM Serial Number", telephonyManager.getSimSerialNumber());

电话号码

为使用电话的设备编写应用时,电话号码可以用作唯一标识符。该标识符在所有版本的 Android 上都可用,并与设备上的 SIM 卡(如果有)绑定,需要READ_PHONE_STATEREAD_PRIVILEGED_PHONE_STATE permission才能访问。

正在检索 的电话号码 :

TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
Log.v("Phone Number", telephonyManager.getLine1Number());

IMEI 和美国

为了唯一识别设备和防止被盗,所有移动设备都被指定了一个 IMEI 或 MEID 号码。取决于设备的网络将取决于设备具有哪个标识符。如果在 GSM(全球移动系统)系统上,设备将具有 IMEI 号码,如果在 CDMA(码分多址)系统上,设备将具有 MEID 号码。两者的主要区别在于 IMEI 是 14 位数字,而 MEID 是 15 位数字。与其他硬件标识符类似,IMEIs 和 MEIDs 都可以在 Android 10 之前的设备上使用,如果应用具有READ_PHONE_STATE权限,就可以读取这些标识符。但是,从 Android 10 开始,一个应用需要READ_PRIVILEGED_PHONE_STATE

Pre 及包含 Android N (25)访问:

TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
Log.v("Device ID", telephonyManager.getDeviceId());

贴吧(含)安卓 O (26):

TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
Log.v("IMEI", telephonyManager.getImei());
Log.v("MEID", telephonyManager.getMeid());
Footnotes [1](#Fn1_source) " Android 安全性第 1 部分:应用签名和权限……"5 月 4 日。2015, [`https://boundarydevices.com/android-security-part-1-application-signatures-permissions/`](https://boundarydevices.com/android-security-part-1-application-signatures-permissions/) 。5 月 11 日访问。2020.   [2](#Fn2_source) "广告 ID -播放控制台帮助-谷歌支持." [`https://support.google.com/googleplay/android-developer/answer/6048248?hl=en-GB`](https://support.google.com/googleplay/android-developer/answer/6048248%253Fhl%253Den-GB) 。5 月 21 日访问。2020.   [3](#Fn3_source) “我的 SIM 卡有序列号吗?和 IMEI 一样吗?." [`https://justaskthales.com/us/does-my-sim-card-have-serial-number-it-same-imei/`](https://justaskthales.com/us/does-my-sim-card-have-serial-number-it-same-imei/) 。5 月 11 日访问。2020.