[Android] Introducción a la identificación única de dispositivos Android

1. Concepto

IMEI
IMEI (International Mobile Equipment Identity) es la abreviatura de International Mobile Equipment Identity. La International Mobile Equipment Identity es un "número de serie electrónico" compuesto por 15 dígitos. Corresponde a cada teléfono móvil uno por uno, y el código está completo El único del mundo. A cada teléfono móvil se le asignará un conjunto de números únicos a nivel mundial después del ensamblaje. Este número será registrado por el fabricante desde la producción hasta la entrega. El código IMEI es asignado uniformemente por GSM (Asociación Global de Comunicaciones Móviles) y autorizado para ser revisado y aceptado por BABT (Comité de Gestión de Certificación de Comunicaciones Británicas).

El IMEI consta de:
1. Los primeros 6 dígitos (TAC, Type ApprovalCode) son el "número de aprobación del modelo" y generalmente representan el modelo.
2. Los siguientes 2
dígitos (FAC, Código de montaje final) es el "Código de montaje final", que generalmente representa el lugar de producción.
3. Los siguientes 6 dígitos (SNR) son el "número de serie", que generalmente representa el número de secuencia de producción. 4. El último dígito (SP) suele ser "0", que es el código de verificación y está reservado.

Generalmente en teléfonos Android, puedes consultarlo en Acerca del teléfono


El Número de identificación de abonado móvil internacional de IMSI (IMSI: Número de identificación de abonado móvil internacional) es un signo que distingue a los usuarios móviles, se almacena en la tarjeta SIM y se puede utilizar para distinguir la información efectiva de los usuarios móviles. La longitud total no supera los 15 dígitos y también se utilizan números del 0 al 9.

ICCID
ICCID: Identidad de tarjeta de circuito integrado (solidificada en la tarjeta SIM del teléfono móvil), que es simplemente el número de serie de la tarjeta SIM. Tiene características únicas, similares al número de serie de un teléfono móvil, y solo apunta a una tarjeta de teléfono móvil. Hay 20 dígitos en total y el formato de codificación es diferente para diferentes operadores. Y los primeros seis dígitos son el código del operador: por ejemplo, China Mobile: 898600; China Unicom: 898601 y China Telecom: 898603.

En resumen: IMEI / MEID está relacionado con el dispositivo, el código de identificación único del dispositivo móvil; mientras que IMSI e ICCID están relacionados con la tarjeta del teléfono móvil, y la información se almacena en la tarjeta del teléfono móvil. Para teléfonos móviles sin una tarjeta de teléfono móvil, puede obtener estos dos El valor es nulo.

二 、 TelephonyManager

//注意代码使用需要在Manifest配置权限
// <uses-permission android: /> 
//在API 23(Android6.0 )及其以上版本phone组权限需要动态申请
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);  
String deviceid = tm.getDeviceId();   //取 IMEI或者MEID
String tel = tm.getLine1Number();     //取出用户手机号码,手机没有安装SIM卡,值为null
String imsi =tm.getSubscriberId();     //取出IMSI,手机没有安装SIM卡,值为null
String imei =tm.getSimSerialNumber();  //取出ICCID,手机没有安装SIM卡,值为null

De hecho, la información anterior se divide en dos partes, una parte es información relacionada con el dispositivo y la otra es información relacionada con la tarjeta SIM. Con respecto a la información relacionada con la tarjeta SIM, en términos generales, no hay forma de marcar el dispositivo, porque el teléfono móvil puede reemplazar la tarjeta SIM a voluntad, y ahora el teléfono móvil tiene doble SIM y doble modo de espera. Para obtener información sobre la adquisición de teléfonos móviles con doble SIM y la información relacionada con la tarjeta del teléfono móvil, consulte este artículo

Nos preocupa principalmente la ID del dispositivo (IMEI o MEID) aquí, y explicamos estas dos cosas: IMEI es la abreviatura de Código de identificación de equipo móvil internacional y MEID es la abreviatura de Código de identificación de equipo móvil, generalmente IMEI está disponible para todos los dispositivos y MEID es general Solo disponible para dispositivos compatibles con el sistema CDMA.

Teléfono OPPO: vaya a configuración del teléfono-general-acerca de la información de estado del teléfono-IMEI para verlo. Mi teléfonos: Configuración-Mi dispositivo-Todos los parámetros-Información de estado-Información IMEI Teléfono Huawei: Configuración-Acerca del teléfono

Nota: la tableta no tiene un número imei

Tres, la identificación única del dispositivo.

1. IMEI alguien MEID

El sistema Android necesita saber algo sobre la compatibilidad con tarjetas duales. En Android 4.xy versiones anteriores, el Android nativo no admite tarjetas duales.
Comenzó a admitir alrededor de 5.x, pero la API está oculta. En Android 6.0 Solo entonces comenzó a abrir la API de doble tarjeta.

Echemos un vistazo a nuestro método básico para obtener IMEI o MEID

//注意动态权限申请
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String imei = telephonyManager.getDeviceId();
这个方法在 4.x 及其以下版本的时候,运行这个方法是没有问题的,因为 4.x 是不支持双卡的,也就是说 4.x 的手机要么是 GSM 要么是 CDMA 制式的。所以,getDeviceId的文档这样写道:

/**
     * Returns the unique device ID, for example, the IMEI for GSM and the MEID
     * or ESN for CDMA phones. Return null if device ID is not available.
     * 翻译过来就是:这个方法会返回唯一的设备id,
     * 比如在GSM的手机上返回的是IMEI,而在CDMA 手机上返回的是MEID或者ESN。
     * 如果设备id不可读取,那么返回null。
     */

Pero esta situación es diferente cuando se trata de Android 6.0 (sin considerar la inestabilidad de la versión 5.x), 6.0 admite tarjetas duales, lo que significa que puede que no haya solo un IMEI o MEID en el teléfono. En este momento, debe estar basado en el teléfono. Se obtiene la ranura de la tarjeta. Qué tarjeta estándar está instalada en esta ranura de tarjeta, luego se obtiene el IMEI o MEID para el subíndice:

public void onClick(View view) {
    
    

        TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);

        Log.d("Q_M", "meid:" + tm.getDeviceId());
        Log.d("Q_M", "meid:" + tm.getDeviceId(0));
        Log.d("Q_M", "meid:" + tm.getDeviceId(1));

    }

El resultado de la prueba proviene de la red, no verifiqué (tengo preguntas sobre la situación sin la tarjeta):

Mis dos tarjetas Unicom son imei1 e imei2

  1、不插卡(或两张卡都是GSM卡)

  getDeviceId()  返回 imei1
  getDeviceId(0) 返回 imei1
  getDeviceId(1) 返回 imei2

  2、卡1插CDMA卡,卡2不插卡(或卡2插GSM卡)

  getDeviceId()   返回 meid
  getDeviceId(0) 返回 meid
  getDeviceId(1) 返回 imei2

  3、卡1不插卡(或卡1插GSM卡)卡2插CDMA卡

  getDeviceId()   返回 imei1
  getDeviceId(0) 返回 imei1
  getDeviceId(1) 返回 meid

Más adelante, en Android 8.0, el control del método se refinó más, por lo que este método getDeviceId se abandonó y ya no se recomienda. Y se recomienda utilizar getImei y getMeid al mismo tiempo. Estos dos métodos admiten el subíndice que se pasa a la ranura de la tarjeta para determinar el valor de la tarjeta que se va a leer. Puede ser muy grave en los teléfonos 8.0 y superiores:

public void onClick(View view) {
    
    

        TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);

        //手机上存在两个imei值,分配给两个卡槽
        Log.d("Q_M", "imei:" + tm.getImei());
        Log.d("Q_M", "imei0:" + tm.getImei(0));
        Log.d("Q_M", "imei1:" + tm.getImei(1));

        //手机上只会存在一个meid,两个卡槽获取的一样
        Log.d("Q_M", "meid:" + tm.getMeid());
        Log.d("Q_M", "meid0:" + tm.getMeid(0));
        Log.d("Q_M", "meid1:" + tm.getMeid(1));
    }

Finalmente, echemos un vistazo a la forma de obtener Imei en el código de Youmeng:

public static String getImeiNew(Context var0) {
    
    
        String var1 = null;

        try {
    
    
            if(var0 != null) {
    
    
                TelephonyManager var2 = (TelephonyManager)var0.getSystemService("phone");
                if(var2 != null && checkPermission(var0, "android.permission.READ_PHONE_STATE")) {
    
    
                    if(VERSION.SDK_INT >= 26) {
    
    
                        try {
    
    
                            Method var3 = var2.getClass().getMethod("getImei", new Class[0]);
                            var3.setAccessible(true);
                            var1 = (String)var3.invoke(var2, new Object[0]);
                        } catch (Exception var4) {
    
    
                            ;
                        }

                        if(TextUtils.isEmpty(var1)) {
    
    
                            var1 = var2.getDeviceId();
                        }
                    } else {
    
    
                        var1 = var2.getDeviceId();
                    }
                }
            }
        } catch (Exception var5) {
    
    
            if(AnalyticsConstants.UM_DEBUG) {
    
    
                MLog.w("No IMEI.", var5);
            }
        }

        return var1;
    }

2. ANDROIDID

Cuando el dispositivo se inicia por primera vez, el sistema generará aleatoriamente un número de 64 bits y guardará el número en forma de cadena hexadecimal. Esta cadena hexadecimal es ANDROID_ID. Cuando se borra el dispositivo, el valor será Reiniciar. Cuando el dispositivo se restaure a la configuración de fábrica, este valor también cambiará. Si el dispositivo está rooteado, este valor se puede cambiar arbitrariamente.

String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

3. Número de serie (número de serie del dispositivo)

Teóricamente, esto viene del hardware, está configurado en la fábrica, pero algunos fabricantes de equipos escribirán un valor al azar.

Build.SERIAL se puede obtener así
cuando api> = 26
Build.getSerial ();

4. Dirección Mac

<!--访问WIFI的权限-->
<uses-permission android:/>

La dirección Mac no se puede obtener de la forma habitual si está por encima de 6.0, es difícil obtenerla por encima de 7.0 y la dirección Mac no es necesariamente única.

1. Vaya al modo de dirección mac después de 6.0

WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo winfo = wifi.getConnectionInfo();
String mac =  winfo.getMacAddress();

2. En 6.0 y 8.0, el método anterior siempre obtendrá 02: 00: 00: 00: 00: 00 en dispositivos 7.0

/**
     * 通过网络接口取
     * 记得添加网络权限
     * <uses-permission android: />
     *
     * @return mac 地址字符串
     */
    private static String getNewMac() {
    
    
        try {
    
    
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
    
    
                if (!nif.getName().equalsIgnoreCase("wlan0")) continue;

                byte[] macBytes = nif.getHardwareAddress();
                if (macBytes == null) {
    
    
                    return null;
                }

                StringBuilder res1 = new StringBuilder();
                for (byte b : macBytes) {
    
    
                    res1.append(String.format("%02X:", b));
                }

                if (res1.length() > 0) {
    
    
                    res1.deleteCharAt(res1.length() - 1);
                }
                return res1.toString();
            }
        } catch (Exception ex) {
    
    
            ex.printStackTrace();
        }
        return null;
    }

Nota: La dirección mac del teléfono móvil se puede ver a través de la línea de comando adb, pero se requiere un teléfono móvil rooteado:

Línea de comando

$ adb shell 
$ su 
$ cat /sys/class/net/wlan0/address

Supongo que te gusta

Origin blog.csdn.net/sinat_36955332/article/details/108702973
Recomendado
Clasificación