Android Q(Android 10)适配

应用读取 Device_ID

Android Q 之前有如下代码,获取设备Id,IMEI等

TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telManager.getDeviceId();
telManager.getImei();

添加下面权限,并且需要动态申请权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

在 Android Q 上调用上面方法会报错

java.lang.SecurityException: getDeviceId: The user xxxx does not meet the requirements to access device identifiers.

或者

E/Exception: getSubscriberId: The user xxxx does not meet the requirements to access device identifiers.
    java.lang.SecurityException: getSubscriberId: The user xxxx does not meet the requirements to access device identifiers.

在 Android Q 上上面方法已经不能使用了,如果获取设备唯一Id,需要使用其他方式了,谷歌提供的获取唯一标识符做法见 文档,也可以用Android_ID,上面这些也不是绝对能得到一个永远不变的Id,可能需要多种方案获取其他Id,比如有谷歌商店的手机可以使用谷歌提供的广告Id,还有其他厂商一般都会提供手机的一个唯一Id。

我们项目现在使用下面这种方式 参考链接。要求生成之后,存储在应用的本地数据库中,读取的时候,优先从本地数据库读取上次存储的设备ID,不要每次都调用下面的接口获取,下面的接口不能保证每次都返回相同结果。

public static String getDeviceId(Context context) {
    final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
    if (targetSdkVersion > Build.VERSION_CODES.P && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
        return getUniqueID(context);
    } else {
        return getTelId(context);
    }
}

private static String getTelId(Context context) {
    final TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    return manager.getDeviceId();
}

private static String getUniqueID(Context context) {
    String id = null;
    final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) {
        try {
            UUID uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
            id = uuid.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    if (TextUtils.isEmpty(id)) {
        id = getUUID();
    }

    return TextUtils.isEmpty(id) ? UUID.randomUUID().toString() : id;
}

private static String getUUID() {
    String serial = null;

    String m_szDevIDShort = "35" +
            Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

            ((null != Build.CPU_ABI) ? Build.CPU_ABI.length() : 0) % 10 + 
            
            Build.DEVICE.length() % 10 + Build.DISPLAY.length() % 10 + 
            
            Build.HOST.length() % 10 + Build.ID.length() % 10 + 
            
            Build.MANUFACTURER.length() % 10 + Build.MODEL.length() % 10 + 
            
            Build.PRODUCT.length() % 10 + Build.TAGS.length() % 10 + 
            
            Build.TYPE.length() % 10 + Build.USER.length() % 10; //13 位

    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                serial = android.os.Build.getSerial();
            } else {
                serial = Build.SERIAL;
            }
            //API>=9 使用serial号
            return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
        } catch (Exception exception) {
            serial = "serial" + UUID.randomUUID().toString(); // 随便一个初始化
        }
    } else {
        serial = android.os.Build.UNKNOWN + UUID.randomUUID().toString(); // 随便一个初始化
    }

    //使用硬件信息拼凑出来的15位号码
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

 

参考链接


发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注