Как я могу получить UUID моего телефона Android в приложении? - PullRequest
49 голосов
/ 23 февраля 2011

Я ищу помощь, чтобы получить UUID моего телефона Android.Я искал в сети и нашел одно потенциальное решение, но оно не работает в эмуляторе.

Вот код:

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

Кто-нибудь знает, почему это не работает, илиесть лучшее решение?

Ответы [ 7 ]

99 голосов
/ 12 апреля 2011

Как упоминает Дейв Уэбб, в блоге разработчиков Android есть статья , в которой об этом говорится. Их предпочтительным решением является отслеживание установок приложений, а не устройств, и это будет хорошо работать в большинстве случаев использования. В блоге будет показан необходимый код для этой работы, и я рекомендую вам проверить его.

Однако в блоге обсуждаются решения, если вам нужен идентификатор устройства, а не идентификатор установки приложения. Я поговорил с кем-то из Google, чтобы получить дополнительные разъяснения по нескольким пунктам на тот случай, если вам нужно это сделать. Вот что я обнаружил об идентификаторах устройств, которые НЕ упомянуты в вышеупомянутом сообщении в блоге:

  • ANDROID_ID является предпочтительным идентификатором устройства. ANDROID_ID абсолютно надежен в версиях Android <= 2.1 или> = 2.3. Только 2.2 имеет проблемы, упомянутые в посте.
  • Ошибка нескольких устройств нескольких производителей от ANDROID_ID в 2.2.
  • Насколько мне удалось определить, все затронутые устройства имеют одинаковый ANDROID_ID , то есть 9774d56d682e549c . Который также является идентичным идентификатором устройства, сообщаемым эмулятором, кстати.
  • Google считает, что производители исправили проблему для многих или большинства своих устройств, но я смог убедиться, что, по крайней мере, по состоянию на начало апреля 2011 года найти устройства с поврежденным ANDROID_ID по-прежнему довольно легко.
  • Когда устройство имеет несколько пользователей (доступно на определенных устройствах под управлением Android 4.2 или выше) , каждый пользователь отображается как совершенно отдельное устройство, поэтому значение ANDROID_ID уникально для каждого пользователя.

Основываясь на рекомендациях Google, я реализовал класс, который будет генерировать уникальный UUID для каждого устройства, используя ANDROID_ID в качестве начального значения, где это необходимо, при необходимости прибегая к TelephonyManager.getDeviceId (), а в случае неудачи прибегая к случайному выбору. сгенерированный уникальный UUID, который сохраняется при перезапуске приложения (но не при переустановке приложения).

Обратите внимание, что для устройств, для которых необходимо использовать идентификатор устройства, уникальный идентификатор WILL сохраняется при сбросе до заводских настроек. Это то, что нужно знать. Если вам необходимо убедиться, что сброс настроек к заводским установкам приведет к сбросу вашего уникального идентификатора, вы можете рассмотреть возможность возврата непосредственно к случайному UUID вместо идентификатора устройства.

Опять же, этот код предназначен для идентификатора устройства, а не идентификатора установки приложения. В большинстве случаев, идентификатор установки приложения, вероятно, то, что вы ищете. Но если вам нужен идентификатор устройства, то, вероятно, вам подойдет следующий код.

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)) {
                                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;
    }
}
62 голосов
/ 23 февраля 2011

Это работает для меня:

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

РЕДАКТИРОВАТЬ:

Вам также необходимо установить android.permission.READ_PHONE_STATE в вашем манифесте.Начиная с Android M, вам нужно запросить это разрешение во время выполнения.

См. Этот ответ: https://stackoverflow.com/a/38782876/1339179

7 голосов
/ 25 января 2013
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
5 голосов
/ 23 декабря 2015

Вместо получения IMEI от TelephonyManager используйте ANDROID_ID.

Settings.Secure.ANDROID_ID

Это работает для каждого устройства Android независимо от наличия телефонии.

4 голосов
/ 01 апреля 2016
1 голос
/ 13 июля 2016

Добавить

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

Метод

String getUUID(){
    TelephonyManager teleManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    String tmSerial = teleManager.getSimSerialNumber();
    String tmDeviceId = teleManager.getDeviceId();
    String androidId = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
    if (tmSerial  == null) tmSerial   = "1";
    if (tmDeviceId== null) tmDeviceId = "1";
    if (androidId == null) androidId  = "1";
    UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDeviceId.hashCode() << 32) | tmSerial.hashCode());
    String uniqueId = deviceUuid.toString();
    return uniqueId;
}
0 голосов
/ 07 сентября 2017

Начиная с API 26, getDeviceId () устарела.Если вам нужно получить IMEI устройства, используйте следующее:

 String deviceId = "";
    if (Build.VERSION.SDK_INT >= 26) {
        deviceId = getSystemService(TelephonyManager.class).getImei();
    }else{
        deviceId = getSystemService(TelephonyManager.class).getDeviceId();
    }
...