Comment trouver le numéro de série de l'appareil Android?


115

Je dois utiliser un identifiant unique pour une application Android et j'ai pensé que le numéro de série de l'appareil serait un bon candidat. Comment récupérer le numéro de série d'un appareil Android dans mon application?


2
N'oubliez pas d'ajouter android: name = "android.permission.READ_PHONE_STATE" à votre manifeste
Michael SIlveus


Si vous souhaitez obtenir un ID unique sans aucune autorisation, vous pouvez utiliser cette bibliothèque pour générer soit un ID unique par appareil avec Identity.getDeviceId (contexte), soit un identifiant pour l'installation de votre application via Identity.getInstallationId (contexte) .
caw

Réponses:


105
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

getSystemService est une méthode de la classe Activity. getDeviceID () renverra le MDN ou MEID de l'appareil en fonction de la radio utilisée par le téléphone (GSM ou CDMA).

Chaque appareil DOIT renvoyer une valeur unique ici (en supposant qu'il s'agisse d'un téléphone). Cela devrait fonctionner pour tout appareil Android avec un slot SIM ou une radio CDMA. Vous êtes seul avec ce micro-ondes alimenté par Android ;-)


@Hasemam Cela ne fonctionne pas pour moi, ce qui donne l'erreur "Force Close"
Paresh Mayani

23
@Hasemam fonctionne correctement maintenant après avoir ajouté l'autorisation <uses-permission android: name = "android.permission.READ_PHONE_STATE"> </uses-permission> dans le fichier androidManifest.xml.
Paresh Mayani

23
Il y a quelques conseils sur le blog officiel du développeur Android sur l'utilisation de cet identifiant: android-developers.blogspot.com/2011/03/…
David Snabel-Caunt

8
à part le micro-ondes alimenté par Android, qu'en est-il d'une tablette alimentée par Android? :)
ajacian81

21
Cette méthode doit être évitée, cela fonctionnera sur les téléphones mais ne fonctionnera pas sur les appareils sans puce de téléphone (les tablettes en sont un exemple). À partir de la version 2.3, vous pouvez utiliser android.os.Build.SERIAL, mais consultez le blog des développeurs suggéré par @DavidCaunt.
John Mitchell

71

Comme le mentionne Dave Webb, le blog des développeurs Android contient un article qui couvre ce sujet.

J'ai parlé avec quelqu'un de Google pour obtenir des éclaircissements supplémentaires sur quelques éléments. Voici ce que j'ai découvert qui n'est PAS mentionné dans l'article de blog susmentionné:

  • ANDROID_ID est la solution préférée. ANDROID_ID est parfaitement fiable sur les versions d'Android <= 2.1 ou> = 2.3. Seul 2.2 a les problèmes mentionnés dans le post.
  • Plusieurs appareils de plusieurs fabricants sont affectés par le bogue ANDROID_ID de la version 2.2.
  • Pour autant que j'ai pu le déterminer, tous les appareils concernés ont le même ANDROID_ID , qui est 9774d56d682e549c . Qui est également le même identifiant de périphérique signalé par l'émulateur, btw.
  • Google pense que les OEM ont corrigé le problème pour la plupart ou la plupart de leurs appareils, mais j'ai pu vérifier qu'au début du mois d'avril 2011, au moins, il est encore assez facile de trouver des appareils dont l'ANDROID_ID est défectueux.

Sur la base des recommandations de Google, j'ai implémenté une classe qui générera un UUID unique pour chaque appareil, en utilisant ANDROID_ID comme graine le cas échéant, en recourant à TelephonyManager.getDeviceId () si nécessaire, et en cas d'échec, en recourant à un UUID unique généré aléatoirement. qui est conservé lors des redémarrages de l'application (mais pas des réinstallations d'application).

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {

    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected static volatile UUID uuid;

    public DeviceUuidFactory(Context context) {
        if (uuid == null) {
            synchronized (DeviceUuidFactory.class) {
                if (uuid == null) {
                    final SharedPreferences prefs = context
                            .getSharedPreferences(PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null);
                    if (id != null) {
                        // Use the ids previously computed and stored in the
                        // prefs file
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(
                            context.getContentResolver(), Secure.ANDROID_ID);
                        // Use the Android ID unless it's broken, in which case
                        // fallback on deviceId,
                        // unless it's not available, then fallback on a random
                        // number which we store to a prefs file
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                uuid = UUID.nameUUIDFromBytes(androidId
                                        .getBytes("utf8"));
                            } else {
                                final String deviceId = ((TelephonyManager) 
                                        context.getSystemService(
                                            Context.TELEPHONY_SERVICE))
                                            .getDeviceId();
                                uuid = deviceId != null ? UUID
                                        .nameUUIDFromBytes(deviceId
                                                .getBytes("utf8")) : UUID
                                        .randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                        // Write the value out to the prefs file
                        prefs.edit()
                                .putString(PREFS_DEVICE_ID, uuid.toString())
                                .commit();
                    }
                }
            }
        }
    }

    /**
     * Returns a unique UUID for the current android device. As with all UUIDs,
     * this unique ID is "very highly likely" to be unique across all Android
     * devices. Much more so than ANDROID_ID is.
     * 
     * The UUID is generated by using ANDROID_ID as the base key if appropriate,
     * falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to
     * be incorrect, and finally falling back on a random UUID that's persisted
     * to SharedPreferences if getDeviceID() does not return a usable value.
     * 
     * In some rare circumstances, this ID may change. In particular, if the
     * device is factory reset a new device ID may be generated. In addition, if
     * a user upgrades their phone from certain buggy implementations of Android
     * 2.2 to a newer, non-buggy version of Android, the device ID may change.
     * Or, if a user uninstalls your app on a device that has neither a proper
     * Android ID nor a Device ID, this ID may change on reinstallation.
     * 
     * Note that if the code falls back on using TelephonyManager.getDeviceId(),
     * the resulting ID will NOT change after a factory reset. Something to be
     * aware of.
     * 
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID
     * directly.
     * 
     * @see http://code.google.com/p/android/issues/detail?id=10603
     * 
     * @return a UUID that may be used to uniquely identify your device for most
     *         purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }
}

1
Quelles autorisations sont nécessaires pour qu'une application utilise cela?
Dave L.

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

1
@ ef2011, c'est le schéma de verrouillage double-vérifié: en.wikipedia.org/wiki/Double-checked_locking
emmby

3
Merci d'avoir posté. Mais qu'est-ce qui empêche quelqu'un avec un téléphone enraciné de simplement modifier device_id.xml pour insérer un nouvel UUID de son choix? (c'est-à-dire pour contourner une vérification «d'essai gratuit») Ne serait-il pas préférable que la classe stocke uniquement la valeur dans un fichier de préférences si elle doit recourir à la méthode d'ID aléatoire? Sinon, il n'est pas nécessaire de le conserver entre les exécutions de l'application; il est plus sûr de se régénérer.
Carlos P

1
"ANDROID_ID" est la solution préférée ". Notez que ANDROID_ID n'identifie plus de manière unique un périphérique: stackoverflow.com/a/13465373/150016
Tom

32
String serial = null; 

try {
    Class<?> c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
} catch (Exception ignored) {
}

Ce code renvoie le numéro de série de l'appareil à l'aide d'une API Android masquée.


7
cela me donne juste la même valeur que celle que j'obtiens avec android.os.Build.SERIAL
josephus

Est-ce que je me trompe ou ce numéro de série est-il le même sur tous les appareils avec une rom personnalisée spécifique? Le numéro de série de mon appareil (dans le lanceur d'appareil eclipse) indique 01234567890ABC pour un téléphone avec une rom personnalisée.
Peterdk

@Peterdk sur mon appareil avec cyanogène-9 les deux méthodes (avant andy-9 comme dans la réponse et la plus simple disponible à partir de andy-9) signalent le bon s / n (le même que sur l'autocollant du fabricant). Cela peut cependant dépendre de la version personnalisée de la rom. Quelle rom / version utilisez-vous?
morgwai

16
String deviceId = Settings.System.getString(getContentResolver(),
                                Settings.System.ANDROID_ID);

Cependant, il n'est pas garanti que l'ID Android sera un identifiant unique.


@Paresh Mayani, il est difficile de dire quel peut être le problème sans regarder le code. Ma seule hypothèse est que getContentResolverc'est de retour null. Cependant, cela peut valoir la peine d'ouvrir une question et de publier votre code.
Anthony Forloney

4
Cet identifiant provient du compte Google associé au téléphone. Le simulateur n'en a généralement pas. Un vrai téléphone peut ne pas en avoir non plus. En outre, il est documenté comme "peut changer lors de la réinitialisation d'usine", et il peut être changé arbitrairement à tout moment sur un téléphone enraciné. À utiliser à vos risques et périls. Il n'y a pas de bonne alternative - les autres ID d'appareil provisoires ne sont pas disponibles universellement, ou ne sont pas uniques, ou les deux. Voir d'autres réponses pour le reste de cette triste histoire.
Seva Alekseyev

14

Il y a un excellent article sur le blog du développeur Android qui en parle .

Il recommande TelephonyManager.getDeviceId()de ne pas l' utiliser car il ne fonctionne pas sur les appareils Android qui ne sont pas des téléphones tels que les tablettes, il nécessite l' READ_PHONE_STATEautorisation et ne fonctionne pas de manière fiable sur tous les téléphones.

Au lieu de cela, vous pouvez utiliser l'un des éléments suivants:

  • Adresse Mac
  • Numéro de série
  • ANDROID_ID

Le message traite des avantages et des inconvénients de chacun et il vaut la peine d'être lu afin que vous puissiez déterminer lequel serait le mieux pour votre utilisation.


+1, salut Dave, merci pour la clarification, car en ce moment, je développe une application pour la tablette, où je dois avoir l'identifiant unique de l'appareil Android, alors que dois-je utiliser pour obtenir une tablette Android unique?
Paresh Mayani

12

Pour un numéro simple qui est unique à l'appareil et constant pour sa durée de vie (sauf réinitialisation d'usine ou piratage), utilisez Settings.Secure.ANDROID_ID .

String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

Pour utiliser le numéro de série de l'appareil (celui indiqué dans «Paramètres système / À propos / État») si disponible et revenir à l'identifiant Android:

String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);

réponse simple !!
faris faris

Build.SERİAL obsolète en java
Eyyüp Alkış

7

L'IMEI est bon mais ne fonctionne que sur les appareils Android avec téléphone. Vous devriez également envisager la prise en charge des tablettes ou d'autres appareils Android, qui n'ont pas de téléphone.

Vous avez des alternatives comme: Construisez des membres de classe, BT MAC, WLAN MAC, ou encore mieux - une combinaison de tout cela.

J'ai expliqué ces détails dans un article sur mon blog, voir: http://www.pocketmagic.net/?p=1662


6

Comme aucune réponse ici ne mentionne un ID parfait et infaillible qui est à la fois PERSISTANT grâce aux mises à jour du système et existe dans TOUS les appareils (principalement en raison du fait qu'il n'y a pas de solution individuelle de Google), j'ai décidé de publier une méthode qui est la meilleure chose suivante en combinant deux des identificateurs disponibles, et une vérification pour choisir entre eux au moment de l'exécution.

Avant le code, 3 faits:

  1. TelephonyManager.getDeviceId()(akaIMEI) ne fonctionnera pas bien ou pas du tout pour les appareils non GSM, 3G, LTE, etc., mais renverra toujours un identifiant unique lorsque le matériel associé est présent , même lorsqu'aucune carte SIM n'est insérée ou même lorsqu'aucun emplacement SIM n'existe ( certains OEM l'ont fait).

  2. Depuis Gingerbread (Android 2.3) android.os.Build.SERIAL doit exister sur tout appareil qui ne fournit pas IMEI , c'est-à-dire qui n'a pas le matériel susmentionné, conformément à la politique Android.

  3. En raison du fait (2.), au moins un de ces deux identifiants uniques sera TOUJOURS présent , et SERIAL peut être présent en même temps que IMEI.

Remarque: les faits (1.) et (2.) sont basés sur les déclarations de Google

SOLUTION

Avec les faits ci-dessus, on peut toujours avoir un identifiant unique en vérifiant s'il existe du matériel lié à IMEI, et revenir à SERIAL quand ce n'est pas le cas, car on ne peut pas vérifier si le SERIAL existant est valide. La classe statique suivante présente 2 méthodes pour vérifier cette présence et utiliser IMEI ou SERIAL:

import java.lang.reflect.Method;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;

public class IDManagement {

    public static String getCleartextID_SIMCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if(isSIMAvailable(mContext,telMgr)){
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId());
            return telMgr.getDeviceId();

        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static String getCleartextID_HARDCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if(telMgr != null && hasTelephony(mContext)){           
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId() + "");

            return telMgr.getDeviceId();    
        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static boolean isSIMAvailable(Context mContext, 
            TelephonyManager telMgr){

        int simState = telMgr.getSimState();

        switch (simState) {
        case TelephonyManager.SIM_STATE_ABSENT:
            return false;
        case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            return false;
        case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_PUK_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_READY:
            return true;
        case TelephonyManager.SIM_STATE_UNKNOWN:
            return false;
        default:
            return false;
        }
    }

    static public boolean hasTelephony(Context mContext)
    {
        TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm == null)
            return false;

        //devices below are phones only
        if (Build.VERSION.SDK_INT < 5)
            return true;

        PackageManager pm = mContext.getPackageManager();

        if (pm == null)
            return false;

        boolean retval = false;
        try
        {
            Class<?> [] parameters = new Class[1];
            parameters[0] = String.class;
            Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
            Object [] parm = new Object[1];
            parm[0] = "android.hardware.telephony";
            Object retValue = method.invoke(pm, parm);
            if (retValue instanceof Boolean)
                retval = ((Boolean) retValue).booleanValue();
            else
                retval = false;
        }
        catch (Exception e)
        {
            retval = false;
        }

        return retval;
    }


}

Je conseillerais sur l'utilisation getCleartextID_HARDCHECK. Si le reflet ne colle pas à votre environnement, utilisez legetCleartextID_SIMCHECK plutôt méthode, mais prenez en considération qu'elle doit être adaptée à vos besoins spécifiques de présence SIM.

PS : Veuillez noter que les OEM ont réussi à écarter SERIAL contre la politique de Google (plusieurs appareils avec le même SERIAL), et Google, comme indiqué, il y a au moins un cas connu dans un grand OEM (non divulgué et je ne sais pas quelle marque c'est non plus, je suppose Samsung).

Avertissement : Cela répond à la question initiale d'obtenir un ID d'appareil unique, mais l'OP a introduit une ambiguïté en déclarant qu'il a besoin d'un ID unique pour une application. Même si pour de tels scénarios, Android_ID serait meilleur, il NE FONCTIONNE PAS après, par exemple, une sauvegarde Titanium d'une application via 2 installations de ROM différentes (peut même être la même ROM). Ma solution maintient une persistance indépendante d'un flash ou d'une réinitialisation d'usine, et n'échouera que lorsque la falsification IMEI ou SERIAL se produit par le biais de hacks / mods matériels.


5

Il y a des problèmes avec toutes les approches ci-dessus. Chez Google i / o, Reto Meier a publié une réponse solide sur la façon d'aborder cela, qui devrait répondre aux besoins de la plupart des développeurs pour suivre les utilisateurs à travers les installations.

Cette approche vous donnera un identifiant utilisateur anonyme et sécurisé qui sera persistant pour l'utilisateur sur différents appareils (y compris les tablettes, en fonction du compte Google principal) et entre les installations sur le même appareil. L'approche de base consiste à générer un ID utilisateur aléatoire et à le stocker dans les préférences partagées des applications. Vous utilisez ensuite l'agent de sauvegarde de Google pour stocker les préférences partagées liées au compte Google dans le cloud.

Passons en revue l'approche complète. Nous devons d'abord créer une sauvegarde de nos SharedPreferences à l'aide du service de sauvegarde Android. Commencez par enregistrer votre application via ce lien: http://developer.android.com/google/backup/signup.html

Google vous donnera une clé de service de sauvegarde que vous devez ajouter au manifeste. Vous devez également indiquer à l'application d'utiliser le BackupAgent comme suit:

<application android:label="MyApplication"
         android:backupAgent="MyBackupAgent">
    ...
    <meta-data android:name="com.google.android.backup.api_key"
        android:value="your_backup_service_key" />
</application>

Ensuite, vous devez créer l'agent de sauvegarde et lui dire d'utiliser l'agent d'assistance pour les préférences partagées:

public class MyBackupAgent extends BackupAgentHelper {
    // The name of the SharedPreferences file
    static final String PREFS = "user_preferences";

    // A key to uniquely identify the set of backup data
    static final String PREFS_BACKUP_KEY = "prefs";

    // Allocate a helper and add it to the backup agent
    @Override
    public void onCreate() {
        SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this,          PREFS);
        addHelper(PREFS_BACKUP_KEY, helper);
    }
}

Pour terminer la sauvegarde, vous devez créer une instance de BackupManager dans votre activité principale:

BackupManager backupManager = new BackupManager(context);

Enfin, créez un ID utilisateur, s'il n'existe pas déjà, et stockez-le dans les SharedPreferences:

  public static String getUserID(Context context) {
            private static String uniqueID = null;
        private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
    if (uniqueID == null) {
        SharedPreferences sharedPrefs = context.getSharedPreferences(
                MyBackupAgent.PREFS, Context.MODE_PRIVATE);
        uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
        if (uniqueID == null) {
            uniqueID = UUID.randomUUID().toString();
            Editor editor = sharedPrefs.edit();
            editor.putString(PREF_UNIQUE_ID, uniqueID);
            editor.commit();

            //backup the changes
            BackupManager mBackupManager = new BackupManager(context);
            mBackupManager.dataChanged();
        }
    }

    return uniqueID;
}

Cet User_ID sera désormais persistant dans toutes les installations, même si l'utilisateur change de périphérique.

Pour plus d'informations sur cette approche, consultez la présentation de Reto ici http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html

Et pour plus de détails sur la mise en œuvre de l'agent de sauvegarde, consultez le site des développeurs ici: http://developer.android.com/guide/topics/data/backup.html Je recommande particulièrement la section en bas sur les tests comme le fait la sauvegarde ne se produit pas instantanément et donc pour tester, vous devez forcer la sauvegarde.


2

Une autre façon consiste à utiliser / sys / class / android_usb / android0 / iSerial dans une application sans aucune autorisation.

user@creep:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
user@creep:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

Pour ce faire en java, il suffit d'utiliser un FileInputStream pour ouvrir le fichier iSerial et lire les caractères. Assurez-vous simplement de l'envelopper dans un gestionnaire d'exceptions, car tous les périphériques n'ont pas ce fichier.

Au moins les appareils suivants sont connus pour avoir ce fichier lisible par tout le monde:

  • Galaxy Nexus
  • Nexus S
  • Motorola Xoom 3g
  • Toshiba AT300
  • HTC One V
  • Mini MK802
  • Samsung Galaxy S II

Vous pouvez également voir mon article de blog ici: http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html où je discute des autres fichiers disponibles pour info.


Merci d'avoir publié votre réponse! Veuillez lire attentivement la FAQ sur l'auto-promotion . Notez également qu'il est nécessaire de publier une clause de non-responsabilité chaque fois que vous créez un lien vers votre propre site / produit.
Andrew Barber

1

Comme le dit @haserman:

TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

Mais il est nécessaire d'inclure l'autorisation dans le fichier manifeste:

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

1

ID d'appareil unique de l'appareil Android OS sous forme de chaîne.

String deviceId;
    final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephony.getDeviceId() != null){
            deviceId = mTelephony.getDeviceId(); 
         }
        else{
            deviceId = Secure.getString(getApplicationContext().getContentResolver(),   Secure.ANDROID_ID); 
         }

mais je recommande vivement cette méthode suggérée par Google:

Identification des installations d'application


1

Build.SERIALest le moyen le plus simple, mais pas entièrement fiable, car il peut être vide ou parfois renvoyer une valeur différente ( preuve 1 , preuve 2 ) que ce que vous pouvez voir dans les paramètres de votre appareil.

Il existe plusieurs façons d'obtenir ce nombre en fonction du fabricant de l'appareil et de la version d'Android, j'ai donc décidé de compiler toutes les solutions possibles que je pouvais trouver en un seul élément . En voici une version simplifiée:

public static String getSerialNumber() {
    String serialNumber;

    try {
        Class<?> c = Class.forName("android.os.SystemProperties");
        Method get = c.getMethod("get", String.class);

        serialNumber = (String) get.invoke(c, "gsm.sn1");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ril.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ro.serialno");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "sys.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = Build.SERIAL;

        // If none of the methods above worked
        if (serialNumber.equals(""))
            serialNumber = null;
    } catch (Exception e) {
        e.printStackTrace();
        serialNumber = null;
    }

    return serialNumber;
}

0

Je sais que cette question est ancienne mais cela peut être fait en une seule ligne de code

String deviceID = Build.SERIAL;


AFAIK, cela changera après la mise à jour du système d'exploitation de l'appareil, par exemple de 4.4.2 à 4.4.4 ou autre.
Den Drobiazko

-1

J'ai trouvé que l'exemple de classe posté par @emmby ci-dessus était un excellent point de départ. Mais il a quelques défauts, comme mentionné par d'autres affiches. Le principal est qu'il persiste inutilement l'UUID dans un fichier XML et le récupère par la suite toujours à partir de ce fichier. Cela ouvre la classe à un piratage facile: toute personne possédant un téléphone enraciné peut modifier le fichier XML pour se donner un nouvel UUID.

J'ai mis à jour le code pour qu'il ne persiste en XML que si cela est absolument nécessaire (c'est-à-dire lors de l'utilisation d'un UUID généré aléatoirement) et re-factorisé la logique selon la réponse de @Brill Pappin:

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {
    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";

    protected static UUID uuid;

    public DeviceUuidFactory(Context context) {

        if( uuid ==null ) {
            synchronized (DeviceUuidFactory.class) {
                if( uuid == null) {
                    final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null );

                    if (id != null) {
                        // Use the ids previously computed and stored in the prefs file
                        uuid = UUID.fromString(id);

                    } else {

                        final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);

                        // Use the Android ID unless it's broken, in which case fallback on deviceId,
                        // unless it's not available, then fallback on a random number which we store
                        // to a prefs file
                        try {
                             if ( "9774d56d682e549c".equals(androidId) || (androidId == null) ) {
                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();

                                if (deviceId != null)
                                {
                                    uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
                                }
                                else
                                {
                                    uuid = UUID.randomUUID();

                                    // Write the value out to the prefs file so it persists
                                    prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
                                }
                            }
                            else
                            {
                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } 
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }



                    }

                }
            }
        }

    }


    /**
     * Returns a unique UUID for the current android device.  As with all UUIDs, this unique ID is "very highly likely"
     * to be unique across all Android devices.  Much more so than ANDROID_ID is.
     *
     * The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on
     * TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back
     * on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a
     * usable value.
     *
     * In some rare circumstances, this ID may change.  In particular, if the device is factory reset a new device ID
     * may be generated.  In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2
     * to a newer, non-buggy version of Android, the device ID may change.  Or, if a user uninstalls your app on
     * a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.
     *
     * Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT
     * change after a factory reset.  Something to be aware of.
     *
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.
     *
     * @see http://code.google.com/p/android/issues/detail?id=10603
     *
     * @return a UUID that may be used to uniquely identify your device for most purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }

Mettre l'identifiant dans des préférences partagées compromet l'objectif initial d'obtenir un identifiant vraiment unique. Par exemple, si vous souhaitez utiliser cet identifiant comme clé pour certaines restrictions, vous serez foutu lorsque des utilisateurs expérimentés rootent un appareil et ont accès à votre fichier de préférences partagé. Son contenu peut être copié, ce qui signifie ...
Eugene Wechsler

il y a aussi une autre erreur dans la réponse de MB et la vôtre. Si vous utilisez randomUUID comme deviceID et appID, cela fonctionne pour tous les appareils à travers le boord, qu'il s'agisse de téléphones ou non ou de dispositifs google exp ou non.
Fred Grott

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.