uniqueidentifier ssaid - Existe-t-il un identifiant de périphérique Android unique?




android_id uuid (25)

Les appareils Android ont-ils un identifiant unique et, le cas échéant, quel moyen simple d'y accéder via Java?


Answers

Google a maintenant un identifiant de publicité .
Cela peut aussi être utilisé, mais notez que:

L'ID de publicité est un ID unique, réinitialisable, spécifique à l'utilisateur.

et

permet aux utilisateurs de réinitialiser leur identifiant ou de désactiver les annonces par centres d'intérêt dans les applications Google Play.

Donc, bien que cet identifiant puisse changer, il semble que bientôt nous n’aurons peut-être pas le choix , cela dépend du but de cet identifiant.

http://developer.android.com/google/play-services/id.html

Copiez-collez le code ici

HTH


En utilisant le code ci-dessous, vous pouvez obtenir l'ID de périphérique unique d'un périphérique Android OS sous forme de chaîne.

deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 

Comme Dave Webb le mentionne, le blog des développeurs Android contient un article sur ce sujet. Leur solution préférée consiste à suivre les installations d'applications plutôt que les appareils, et cela fonctionnera bien pour la plupart des cas d'utilisation. L'article de blog vous montrera le code nécessaire pour que cela fonctionne, et je vous recommande de le vérifier.

Cependant, l'article de blog continue pour discuter des solutions si vous avez besoin d'un identifiant de périphérique plutôt que d'un identifiant d'installation d'application. J'ai parlé à quelqu'un chez Google pour obtenir des éclaircissements supplémentaires sur quelques éléments au cas où vous en auriez besoin. Voici ce que j'ai découvert sur les identificateurs de périphérique, qui n'est PAS mentionné dans l'article de blog susmentionné:

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

Sur la base des recommandations de Google, j'ai implémenté une classe qui générera un UUID unique pour chaque périphérique, en utilisant ANDROID_ID comme source, le cas échéant, en recourant à TelephonyManager.getDeviceId () si nécessaire, et en cas d'échec, en recourant à un UUID unique généré de manière aléatoire. qui persiste lors des redémarrages d'applications (mais pas pour les réinstallations d'applications).

Notez que pour les périphériques qui doivent se replier sur l'ID de périphérique, l'ID unique persistera après les réinitialisations d'usine. C'est quelque chose à prendre en compte. Si vous devez vous assurer qu'une réinitialisation d'usine réinitialisera votre ID unique, vous voudrez peut-être envisager de vous replier directement sur l'UUID aléatoire au lieu de l'ID de périphérique.

Encore une fois, ce code concerne un ID de périphérique, pas un ID d'installation d'application. Dans la plupart des situations, un ID d'installation d'application est probablement ce que vous recherchez. Mais si vous avez besoin d'un ID de périphérique, le code suivant fonctionnera probablement pour vous.

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 volatile 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)) {
                                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;
    }
}

Le Mac ID du périphérique Android est également un identifiant unique. Cela ne changera pas si nous formatons le périphérique lui-même. Utilisez donc le code suivant pour obtenir le Mac ID.

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
String address = info.getMacAddress();

Aussi, n'oubliez pas d'ajouter les autorisations appropriées dans votre AndroidManifest.xml

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

Voici comment je génère l'identifiant unique:

import android.Manifest.permission;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

// TODO : hash
public final class DeviceIdentifier {

    private DeviceIdentifier() {}

    /** @see http://code.google.com/p/android/issues/detail?id=10603 */
    private static final String ANDROID_ID_BUG_MSG = "The device suffers from "
        + "the Android ID bug - its ID is the emulator ID : "
        + IDs.BUGGY_ANDROID_ID;
    private static volatile String uuid; // volatile needed - see EJ item 71
    // need lazy initialization to get a context

    /**
     * Returns a unique identifier for this device. The first (in the order the
     * enums constants as defined in the IDs enum) non null identifier is
     * returned or a DeviceIDException is thrown. A DeviceIDException is also
     * thrown if ignoreBuggyAndroidID is false and the device has the Android ID
     * bug
     *
     * @param ctx
     *            an Android constant (to retrieve system services)
     * @param ignoreBuggyAndroidID
     *            if false, on a device with the android ID bug, the buggy
     *            android ID is not returned instead a DeviceIDException is
     *            thrown
     * @return a *device* ID - null is never returned, instead a
     *         DeviceIDException is thrown
     * @throws DeviceIDException
     *             if none of the enum methods manages to return a device ID
     */
    public static String getDeviceIdentifier(Context ctx,
            boolean ignoreBuggyAndroidID) throws DeviceIDException {
        String result = uuid;
        if (result == null) {
            synchronized (DeviceIdentifier.class) {
                result = uuid;
                if (result == null) {
                    for (IDs id : IDs.values()) {
                        try {
                            result = uuid = id.getId(ctx);
                        } catch (DeviceIDNotUniqueException e) {
                            if (!ignoreBuggyAndroidID)
                                throw new DeviceIDException(e);
                        }
                        if (result != null) return result;
                    }
                    throw new DeviceIDException();
                }
            }
        }
        return result;
    }

    private static enum IDs {
        TELEPHONY_ID {

            @Override
            String getId(Context ctx) {
                // TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
                final TelephonyManager tm = (TelephonyManager) ctx
                        .getSystemService(Context.TELEPHONY_SERVICE);
                if (tm == null) {
                    w("Telephony Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.READ_PHONE_STATE);
                return tm.getDeviceId();
            }
        },
        ANDROID_ID {

            @Override
            String getId(Context ctx) throws DeviceIDException {
                // no permission needed !
                final String andoidId = Secure.getString(
                    ctx.getContentResolver(),
                    android.provider.Settings.Secure.ANDROID_ID);
                if (BUGGY_ANDROID_ID.equals(andoidId)) {
                    e(ANDROID_ID_BUG_MSG);
                    throw new DeviceIDNotUniqueException();
                }
                return andoidId;
            }
        },
        WIFI_MAC {

            @Override
            String getId(Context ctx) {
                WifiManager wm = (WifiManager) ctx
                        .getSystemService(Context.WIFI_SERVICE);
                if (wm == null) {
                    w("Wifi Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
                // getMacAddress() has no java doc !!!
                return wm.getConnectionInfo().getMacAddress();
            }
        },
        BLUETOOTH_MAC {

            @Override
            String getId(Context ctx) {
                BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
                if (ba == null) {
                    w("Bluetooth Adapter not available");
                    return null;
                }
                assertPermission(ctx, permission.BLUETOOTH);
                return ba.getAddress();
            }
        }
        // TODO PSEUDO_ID
        // http://www.pocketmagic.net/2011/02/android-unique-device-id/
        ;

        static final String BUGGY_ANDROID_ID = "9774d56d682e549c";
        private final static String TAG = IDs.class.getSimpleName();

        abstract String getId(Context ctx) throws DeviceIDException;

        private static void w(String msg) {
            Log.w(TAG, msg);
        }

        private static void e(String msg) {
            Log.e(TAG, msg);
        }
    }

    private static void assertPermission(Context ctx, String perm) {
        final int checkPermission = ctx.getPackageManager().checkPermission(
            perm, ctx.getPackageName());
        if (checkPermission != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Permission " + perm + " is required");
        }
    }

    // =========================================================================
    // Exceptions
    // =========================================================================
    public static class DeviceIDException extends Exception {

        private static final long serialVersionUID = -8083699995384519417L;
        private static final String NO_ANDROID_ID = "Could not retrieve a "
            + "device ID";

        public DeviceIDException(Throwable throwable) {
            super(NO_ANDROID_ID, throwable);
        }

        public DeviceIDException(String detailMessage) {
            super(detailMessage);
        }

        public DeviceIDException() {
            super(NO_ANDROID_ID);
        }
    }

    public static final class DeviceIDNotUniqueException extends
            DeviceIDException {

        private static final long serialVersionUID = -8940090896069484955L;

        public DeviceIDNotUniqueException() {
            super(ANDROID_ID_BUG_MSG);
        }
    }
}

Pour la reconnaissance matérielle d'un périphérique Android spécifique, vous pouvez vérifier les adresses MAC.

vous pouvez le faire de cette façon:

dans AndroidManifest.xml

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

maintenant dans votre code:

List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());

for (NetworkInterface interface : interfacesList) {
   // This will give you the interface MAC ADDRESS
   interface.getHardwareAddress();
}

Dans tous les appareils Android, leur interface est au moins "wlan0" et constitue la puce WI-FI. Ce code fonctionne même lorsque WI-FI n'est pas activé.

PS Il y a beaucoup d'autres interfaces que vous obtiendrez de la liste contenant les MACS, mais cela peut changer d'un téléphone à l'autre.


Pour obtenir des instructions détaillées sur l'obtention d'un identifiant unique pour chaque périphérique Android à partir duquel votre application est installée, voir la publication officielle sur le blog Android Developers intitulée android-developers.blogspot.com/2011/03/… .

Il semble que le meilleur moyen consiste à en créer un vous-même lors de l'installation et à le lire ensuite au redémarrage de l'application.

Personnellement, je trouve cela acceptable mais pas idéal. Aucun identifiant fourni par Android ne fonctionne dans tous les cas, car la plupart dépendent des états radio du téléphone (Wi-Fi activé / désactivé, cellulaire activé / désactivé, Bluetooth activé / désactivé). Les autres, comme Settings.Secure.ANDROID_IDdoivent être mis en œuvre par le fabricant et ne sont pas garantis d'être unique.

Voici un exemple d’écriture de données dans un fichier d’ installation qui serait stocké avec toutes les autres données que l’application enregistre localement.

public class Installation {
    private static String sID = null;
    private static final String INSTALLATION = "INSTALLATION";

    public synchronized static String id(Context context) {
        if (sID == null) {
            File installation = new File(context.getFilesDir(), INSTALLATION);
            try {
                if (!installation.exists())
                    writeInstallationFile(installation);
                sID = readInstallationFile(installation);
            } 
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return sID;
    }

    private static String readInstallationFile(File installation) throws IOException {
        RandomAccessFile f = new RandomAccessFile(installation, "r");
        byte[] bytes = new byte[(int) f.length()];
        f.readFully(bytes);
        f.close();
        return new String(bytes);
    }

    private static void writeInstallationFile(File installation) throws IOException {
        FileOutputStream out = new FileOutputStream(installation);
        String id = UUID.randomUUID().toString();
        out.write(id.getBytes());
        out.close();
    }
}

Vous pouvez également considérer l'adresse MAC de l'adaptateur Wi-Fi. Récupéré ainsi:

WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();

Nécessite l'autorisation android.permission.ACCESS_WIFI_STATE dans le manifeste.

Signalé comme étant disponible même lorsque le Wi-Fi n'est pas connecté. Si Joe de la réponse ci-dessus donne à celui-ci un essai sur ses nombreux périphériques, ce serait bien.

Sur certains appareils, il n'est pas disponible lorsque le Wi-Fi est désactivé.

REMARQUE: à partir d'Android 6.x, il renvoie une fausse adresse mac cohérente: 02:00:00:00:00:00


ID d'instance Google

Publié à I / O 2015; sur Android nécessite des services de jeu 7.5.

https://developers.google.com/instance-id/
https://developers.google.com/instance-id/guides/android-implementation

InstanceID iid = InstanceID.getInstance( context );   // Google docs are wrong - this requires context
String id = iid.getId();  // blocking call

Il semble que Google ait l'intention d'utiliser cet identifiant pour identifier les installations sous Android, Chrome et iOS.

Il identifie une installation plutôt qu'un périphérique, mais encore une fois, ANDROID_ID (qui est la réponse acceptée) n'identifie plus non plus les périphériques. Avec le runtime ARC, un nouvel ANDROID_ID est généré pour chaque installation (voir les détails ici ), tout comme ce nouvel ID d'instance. De plus, je pense que l’identification des installations (et non des périphériques) est ce que la plupart d’entre nous recherchent réellement.

Les avantages de l'instance ID

Il me semble que Google a l'intention de l'utiliser à cette fin (identifiant vos installations), il est multi-plateforme et peut être utilisé à plusieurs autres fins (voir les liens ci-dessus).

Si vous utilisez GCM, vous devrez éventuellement utiliser cet ID d'instance, car vous en aurez besoin pour obtenir le jeton GCM (qui remplace l'ancien ID d'enregistrement GCM).

Les inconvénients / problèmes

Dans l'implémentation actuelle (GPS 7.5), l'ID d'instance est extrait d'un serveur lorsque votre application le demande. Cela signifie que l’appel ci-dessus est un appel bloquant - lors de tests non scientifiques, cela prend 1 à 3 secondes si l’appareil est en ligne et 0,5 à 1,0 seconde s’il est hors ligne (vraisemblablement combien de temps il attend avant d’abandonner et de générer une identification aléatoire). Cela a été testé en Amérique du Nord sur Nexus 5 avec Android 5.1.1 et GPS 7.5.

Si vous utilisez l'ID aux fins auxquelles ils sont destinés - par exemple. authentification de l'application, identification de l'application, GCM - Je pense que ces 1 à 3 secondes pourraient être une gêne (en fonction de votre application, bien sûr).


Voici le code utilisé par Reto Meier dans la présentation de Google I / O cette année pour obtenir un identifiant unique pour l'utilisateur:

private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";

public synchronized static String id(Context context) {
    if (uniqueID == null) {
        SharedPreferences sharedPrefs = context.getSharedPreferences(
                PREF_UNIQUE_ID, 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();
        }
    }
    return uniqueID;
}

Si vous associez ceci à une stratégie de sauvegarde pour envoyer des préférences vers le cloud (également décrit dans l’ talk de Reto, vous devriez avoir un identifiant qui se connecte à un utilisateur et reste visible après le nettoyage ou le remplacement de l’appareil. Je prévois de l'utiliser. dans les analyses à venir (en d’autres termes, je n’ai pas encore fait ce travail :).



Un champ Serial été ajouté à la Buildclasse dans l’API de niveau 9 (Android 2.3 - Gingerbread). La documentation indique qu'il représente le numéro de série du matériel. Ainsi, il devrait être unique, s'il existe sur le périphérique.

Je ne sais pas s'il est réellement pris en charge (= pas null) par tous les périphériques avec un niveau d'API> = 9 bien.


Il y a plus de 30 réponses ici et certaines sont identiques et d'autres uniques. Cette réponse est basée sur peu de ces réponses. L'un d'eux est la réponse de @Lenn Dolling.

Il combine 3 ID et crée une chaîne hexadécimale de 32 chiffres. Cela a très bien fonctionné pour moi.

Les 3 ID sont les suivants:
Pseudo-ID - Il est généré sur la base des spécifications du périphérique physique
ANDROID_ID - Settings.Secure.ANDROID_ID
Adresse Bluetooth - Adresse de l' adaptateur Bluetooth

Il retournera quelque chose comme ceci: 551F27C060712A72730B0A0F734064B1

Remarque: vous pouvez toujours ajouter d'autres identifiants à la longIdchaîne. Par exemple, numéro de série. adresse de l'adaptateur wifi. IMEI. De cette façon, vous le rendez plus unique par appareil.

@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {

        String pseudoId = "35" +
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 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;

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

        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String btId = "";

        if (bluetoothAdapter != null) {
            btId = bluetoothAdapter.getAddress();
        }

        String longId = pseudoId + androidId + btId;

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(longId.getBytes(), 0, longId.length());

            // get md5 bytes
            byte md5Bytes[] = messageDigest.digest();

            // creating a hex string
            String identifier = "";

            for (byte md5Byte : md5Bytes) {
                int b = (0xFF & md5Byte);

                // if it is a single digit, make sure it have 0 in front (proper padding)
                if (b <= 0xF) {
                    identifier += "0";
                }

                // add number to string
                identifier += Integer.toHexString(b);
            }

            // hex string to uppercase
            identifier = identifier.toUpperCase();
            return identifier;
        } catch (Exception e) {
            Log.e("TAG", e.toString());
        }
        return "";
}

Chez Google I / O, Reto Meier a publié une réponse précise sur la manière d’aborder cette question, ce qui devrait permettre à la plupart des développeurs de suivre les utilisateurs d’une installation à l’autre. Anthony Nolan indique la direction dans sa réponse, mais je pensais écrire l'approche complète afin que les autres puissent facilement voir comment le faire (cela m'a pris un certain temps pour comprendre les détails).

Cette approche vous donnera un ID utilisateur anonyme et sécurisé qui sera persistant pour l'utilisateur sur différents appareils (en fonction du compte Google principal) et pour toutes les installations. 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. Tout d'abord, nous devons créer une sauvegarde pour nos références partagées à l'aide du service de sauvegarde Android. Commencez par enregistrer votre application via http://developer.android.com/google/backup/signup.html .

Google vous fournira une clé de service de sauvegarde que vous devrez ajouter au manifeste. Vous devez également indiquer à l'application d'utiliser 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 auxiliaire 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 ID utilisateur sera désormais persistant dans toutes les installations, même si l'utilisateur déplace un périphérique.

Pour plus d'informations sur cette approche, voir la talk .

Et pour plus de détails sur la mise en œuvre de l'agent de sauvegarde, voir Sauvegarde des données . Je recommande particulièrement la section du bas sur les tests, car la sauvegarde ne se produit pas instantanément et vous devez donc la forcer.


Il y a des informations plutôt utiles here .

Il couvre cinq types d'identification différents:

  1. IMEI (uniquement pour les appareils Android utilisant le téléphone; nécessite android.permission.READ_PHONE_STATE )
  2. Pseudo-Unique ID (pour tous les appareils Android)
  3. Android ID (peut être nul, peut changer lors de la réinitialisation d'usine, peut être modifié sur le téléphone enraciné)
  4. Adresse MAC MAC WLAN (nécessite android.permission.ACCESS_WIFI_STATE )
  5. Chaîne d’ adresse MAC MAC (appareils avec Bluetooth, nécessite android.permission.BLUETOOTH )

Je pense que c’est là un moyen sûr de construire un squelette pour une identité unique ... jetez-y un œil.

Pseudo-unique ID qui fonctionne sur tous les appareils Android Certains appareils ne disposent pas d'un téléphone (par exemple, des tablettes) ou pour une raison quelconque, vous ne souhaitez pas inclure l'autorisation READ_PHONE_STATE. Vous pouvez toujours lire des informations telles que la version de la ROM, le nom du fabricant, le type de CPU et d'autres informations matérielles, qui vous seront utiles si vous souhaitez utiliser l'ID pour la vérification d'une clé de série ou à d'autres fins générales. L'ID calculé de cette manière ne sera pas unique: il est possible de trouver deux périphériques avec le même ID (basés sur le même matériel et la même image ROM), mais les modifications dans les applications réelles sont négligeables. Pour cela, vous pouvez utiliser la classe Build:

String m_szDevIDShort = "35" + //we make this look like a valid IMEI
            Build.BOARD.length()%10+ Build.BRAND.length()%10 +
            Build.CPU_ABI.length()%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 digits

La plupart des membres de Build sont des chaînes, ce que nous faisons ici est de prendre leur longueur et de la transformer via modulo en un chiffre. Nous avons 13 chiffres de ce type et nous en ajoutons deux devant (35) pour avoir le même identifiant de taille que l’IMEI (15 chiffres). Il y a d'autres possibilités ici, jetez un coup d'œil à ces chaînes. Retourne quelque chose comme 355715565309247. Aucune autorisation spéciale n'est requise, ce qui rend cette approche très pratique.

(Extra info: La technique donnée ci-dessus a été copiée d'un article sur here .)


Settings.Secure#ANDROID_ID renvoie l'ID Android sous la forme d'une chaîne unique pour chaque chaîne hexagonale de 64 bits de l' utilisateur .

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID); 

Plus précisément, Settings.Secure.ANDROID_ID. Il s'agit d'une quantité de 64 bits générée et stockée lors du premier démarrage du périphérique. Il est réinitialisé lorsque le périphérique est effacé.

ANDROID_IDsemble être un bon choix pour un identifiant unique de périphérique. Il y a des inconvénients: premièrement, il n'est pas fiable à 100% sur les versions d'Android antérieures à la version 2.2. (“Froyo”).De plus, il y a eu au moins un bogue largement observé dans un combiné populaire d'un grand fabricant, où chaque instance a le même ANDROID_ID.


Que diriez-vous de l' IMEI . C'est unique pour Android ou d'autres appareils mobiles.


Ajoutez le code ci-dessous dans le fichier de classe:

final TelephonyManager tm = (TelephonyManager) getBaseContext()
            .getSystemService(SplashActivity.TELEPHONY_SERVICE);
    final String tmDevice, tmSerial, androidId;
    tmDevice = "" + tm.getDeviceId();
    Log.v("DeviceIMEI", "" + tmDevice);
    tmSerial = "" + tm.getSimSerialNumber();
    Log.v("GSM devices Serial Number[simcard] ", "" + tmSerial);
    androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(),
            android.provider.Settings.Secure.ANDROID_ID);
    Log.v("androidId CDMA devices", "" + androidId);
    UUID deviceUuid = new UUID(androidId.hashCode(),
            ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
    String deviceId = deviceUuid.toString();
    Log.v("deviceIdUUID universally unique identifier", "" + deviceId);
    String deviceModelName = android.os.Build.MODEL;
    Log.v("Model Name", "" + deviceModelName);
    String deviceUSER = android.os.Build.USER;
    Log.v("Name USER", "" + deviceUSER);
    String devicePRODUCT = android.os.Build.PRODUCT;
    Log.v("PRODUCT", "" + devicePRODUCT);
    String deviceHARDWARE = android.os.Build.HARDWARE;
    Log.v("HARDWARE", "" + deviceHARDWARE);
    String deviceBRAND = android.os.Build.BRAND;
    Log.v("BRAND", "" + deviceBRAND);
    String myVersion = android.os.Build.VERSION.RELEASE;
    Log.v("VERSION.RELEASE", "" + myVersion);
    int sdkVersion = android.os.Build.VERSION.SDK_INT;
    Log.v("VERSION.SDK_INT", "" + sdkVersion);

Ajouter dans AndroidManifest.xml:

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

Il existe de nombreuses approches différentes pour ANDROID_IDrésoudre ces problèmes (que ce soit nullparfois ou que les appareils d’un modèle spécifique renvoient toujours le même ID) avec des avantages et des inconvénients:

  • Implémentation d'un algorithme de génération d'identifiant personnalisé (basé sur des propriétés de périphérique censées être statiques et qui ne changeront pas -> qui sait)
  • Utilisation abusive d'autres identifiants comme IMEI , IMEI série, adresse Wi-Fi / Bluetooth-MAC (ils n'existeront pas sur tous les appareils ou des autorisations supplémentaires deviennent nécessaires)

Je préfère moi-même utiliser une implémentation OpenUDID existante (voir https://github.com/ylechelle/OpenUDID ) pour Android (voir https://github.com/vieux/OpenUDID ). Il est facile à intégrer et utilise les solutions de ANDROID_IDrechange pour les problèmes mentionnés ci-dessus.


TelephonyManger.getDeviceId () Renvoie l'ID de périphérique unique, par exemple, l'IMEI pour GSM et le MEID ou l'ESN pour les téléphones CDMA.

final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);            
String myAndroidDeviceId = mTelephony.getDeviceId(); 

Mais je recommande d'utiliser:

Settings.Secure.ANDROID_ID qui renvoie l'ID Android sous forme de chaîne hexagonale unique de 64 bits.

    String   myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 

Parfois TelephonyManger.getDeviceId () retournera null, alors pour assurer un identifiant unique, vous utiliserez cette méthode:

public String getUniqueID(){    
    String myAndroidDeviceId = "";
    TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    if (mTelephony.getDeviceId() != null){
        myAndroidDeviceId = mTelephony.getDeviceId(); 
    }else{
         myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
    }
    return myAndroidDeviceId;
}

Le code suivant renvoie le numéro de série du périphérique à l'aide d'une API Android masquée. Cependant, ce code ne fonctionne pas sur Samsung Galaxy Tab car "ro.serialno" n'est pas défini sur cet appareil.

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) {

}

Une autre méthode consiste à utiliser /sys/class/android_usb/android0/iSerialune application sans aucune autorisation.

[email protected]:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
[email protected]:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

Pour cela, 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 ne possèdent pas ce fichier.

Au moins les périphériques 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 Leaking Android serial number to serial apps, où je discute des autres fichiers qui sont disponibles pour information.


S'il vous plaît essayez ce code ci-dessous dans onCreate()

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);




android uniqueidentifier