Существует ли уникальный идентификатор устройства Android? - PullRequest
2562 голосов
/ 07 мая 2010

Имеют ли устройства Android уникальный идентификатор, и если да, то какой простой способ получить к нему доступ с помощью Java?

Ответы [ 43 ]

1869 голосов
/ 07 мая 2010

Settings.Secure#ANDROID_ID возвращает идентификатор Android в виде , уникального для каждого пользователя 64-битная шестнадцатеричная строка.

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID); 
1106 голосов
/ 18 мая 2010

ОБНОВЛЕНИЕ : В последних версиях Android многие проблемы с ANDROID_ID были решены, и я считаю, что такой подход больше не нужен. Пожалуйста, взгляните на ответ Энтони .

Полное раскрытие: мое приложение изначально использовало описанный ниже подход, но больше не использует этот подход, и теперь мы используем подход, описанный в блоге Android Developer Blog , который emmby's answer ссылается на (а именно, создание и сохранение UUID#randomUUID()).


Есть много ответов на этот вопрос, большинство из которых будет работать только «некоторое время», и, к сожалению, этого недостаточно.

На основании моих тестов устройств (все телефоны, хотя бы один из которых не активирован):

  1. Все протестированные устройства вернули значение для TelephonyManager.getDeviceId()
  2. Все устройства GSM (все протестированы с SIM-картой) вернули значение для TelephonyManager.getSimSerialNumber()
  3. Все устройства CDMA вернули ноль для getSimSerialNumber() (как и ожидалось)
  4. Все устройства с добавленной учетной записью Google вернули значение ANDROID_ID
  5. Все устройства CDMA вернули одно и то же значение (или производное одного и того же значения) для ANDROID_ID и TelephonyManager.getDeviceId() - , если учетная запись Google была добавлена ​​во время установки.
  6. У меня еще не было возможности протестировать устройства GSM без SIM-карты, устройство GSM без добавленной учетной записи Google или какое-либо из устройств в режиме полета.

Так что если вы хотите что-то уникальное для самого устройства, TM.getDeviceId() должно быть достаточно . Очевидно, что некоторые пользователи более параноидальны, чем другие, поэтому может быть полезно хешировать 1 или более этих идентификаторов, чтобы строка по-прежнему оставалась практически уникальной для устройства, но явно не идентифицировала фактическое устройство пользователя. Например, используя String.hashCode() в сочетании с UUID:

final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);

final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();

может привести к чему-то вроде: 00000000-54b3-e7c7-0000-000046bffd97

Это работает достаточно хорошо для меня.

Как упоминает Ричард ниже, не забывайте, что вам нужно разрешение на чтение свойств TelephonyManager, поэтому добавьте это в свой манифест:

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

импортные библиотеки

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
410 голосов
/ 13 июля 2013

Последнее обновление: 6/2/15


После прочтения каждого сообщения о переполнении стека о создании уникального идентификатора, блога разработчиков Google и документации по Android я чувствую, что «псевдоидентификация» - лучший из возможных вариантов.

Основная проблема: оборудование против программного обеспечения

Оборудование

  • Пользователи могут менять свое оборудование, планшет Android или телефон, поэтому уникальные идентификаторы, основанные на оборудовании, не являются хорошими идеями для отслеживания пользователей
  • Для ОБОРУДОВАНИЕ ДЛЯ ОТСЛЕЖИВАНИЯ , это отличная идея

Программное обеспечение

  • Пользователи могут стирать / изменять свои ПЗУ, если они имеют root-права
  • Вы можете отслеживать пользователей на разных платформах (iOS, Android, Windows и Web)
  • Лучшее желание ОТКРЫТЬ ИНДИВИДУАЛЬНОГО ПОЛЬЗОВАТЕЛЯ с их согласием состоит в том, чтобы просто заставить его войти (сделать это без проблем, используя OAuth)

Общая разбивка с Android

- Гарантия уникальности (включая рутированные устройства) для API> = 9/10 (99,5% устройств Android)

- Без дополнительных разрешений

Код Psuedo:

if API >= 9/10: (99.5% of devices)

return unique ID containing serial id (rooted devices may be different)

else

return the unique ID of build information (may overlap data - API < 9)

Спасибо @stansult за публикацию всех наших опций (в этом вопросе о переполнении стека).

Список опций - причины, почему / почему не стоит их использовать:

  • Электронная почта пользователя - Программное обеспечение

  • Номер телефона пользователя - Программное обеспечение

    • Пользователи могут менять номера телефонов - крайне маловероятно
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI - Аппаратное обеспечение (только телефоны, потребности android.permission.READ_PHONE_STATE)

    • Большинство пользователей ненавидят тот факт, что в разрешении написано «Телефонные звонки». Некоторые пользователи дают плохие оценки, потому что они считают, что вы просто крадете их личную информацию, когда все, что вы действительно хотите сделать, это отслеживать установку устройства. Очевидно, что вы собираете данные.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Идентификатор Android - аппаратное обеспечение (может быть нулевым, может изменяться при сбросе к заводским настройкам, может быть изменено на корневом устройстве)

    • Так как он может быть «нулевым», мы можем проверить «нулевое» и изменить его значение, но это означает, что он больше не будет уникальным.
    • Если у вас есть пользователь с устройством сброса к заводским настройкам, значение может быть изменено или изменено на корневом устройстве, поэтому могут быть дубликаты записей, если вы отслеживаете установки пользователей.
  • MAC-адрес WLAN - аппаратное обеспечение (необходимо android.permission.ACCESS_WIFI_STATE)

    • Это может быть второй лучший вариант, но вы все еще собираете и храните уникальный идентификатор, который приходит непосредственно от пользователя. Это очевидно, что вы собираете данные.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • MAC-адрес Bluetooth - аппаратное обеспечение (устройства с Bluetooth, требуется android.permission.BLUETOOTH)

    • Большинство приложений на рынке не используют Bluetooth, и поэтому, если ваше приложение не использует Bluetooth, и вы включаете его, пользователь может заподозрить.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Псевдо-уникальный идентификатор - Программное обеспечение (для всех устройств Android)

    • Очень возможно, может содержать коллизии - см. Мой метод, опубликованный ниже!
    • Это позволяет вам иметь «почти уникальный» идентификатор пользователя, не принимая ничего личного. Вы можете создать свой собственный анонимный идентификатор из информации об устройстве.

Я знаю, что не существует «идеального» способа получения уникального идентификатора без использования разрешений; Однако иногда нам действительно нужно отслеживать установку устройства. Когда дело доходит до создания уникального идентификатора, мы можем создать «псевдо уникальный идентификатор», основываясь исключительно на информации, которую API-интерфейс Android предоставляет нам без использования дополнительных разрешений. Таким образом, мы можем проявить уважение к пользователю и попытаться предложить хороший пользовательский опыт.

С псевдо-уникальным идентификатором вы действительно сталкиваетесь только с тем фактом, что могут быть дубликаты, основанные на том факте, что существуют подобные устройства. Вы можете настроить комбинированный метод, чтобы сделать его более уникальным; однако некоторым разработчикам необходимо отслеживать установку устройств, и это будет способствовать достижению цели или повышению производительности на основе аналогичных устройств.

API> = 9:

Если их Android-устройство имеет API 9 или более поздней версии, оно гарантированно будет уникальным из-за поля Build.SERIAL.

ПОМНИТЕ , технически вы пропускаете только около 0,5% пользователей , у которых API <9 </a>. Таким образом, вы можете сосредоточиться на остальном: это 99,5% пользователей!

API <9: </h2> Если Android-устройство пользователя ниже API 9; надеюсь, что они не сделали сброс к заводским настройкам, и их «Secure.ANDROID_ID» будет сохранен или не будет «нулевым». (см. http://developer.android.com/about/dashboards/index.html) Если ничего не помогает:

Если все остальное терпит неудачу, если пользователь имеет более низкий, чем API 9 (ниже, чем Gingerbread), сбросил свое устройство или «Secure.ANDROID_ID» возвращает «ноль», то просто возвращенный идентификатор будет основан исключительно на его Android Информация об устройстве. Вот где могут произойти столкновения.

Изменения:

  • Удален «Android.SECURE_ID» из-за сброса настроек, что может привести к изменению значения
  • Отредактировал код для изменения в API
  • изменил псевдо

Пожалуйста, посмотрите на метод ниже:

/**
 * Return pseudo unique ID
 * @return ID
 */
public static String getUniquePsuedoID() {
    // If all else fails, if the user does have lower than API 9 (lower
    // than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
    // returns 'null', then simply the ID returned will be solely based
    // off their Android device information. This is where the collisions
    // can happen.
    // Thanks http://www.pocketmagic.net/?p=1662!
    // Try not to use DISPLAY, HOST or ID - these items could change.
    // If there are collisions, there will be overlapping data
    String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);

    // Thanks to @Roman SL!
    // https://stackoverflow.com/a/4789483/950427
    // Only devices with API >= 9 have android.os.Build.SERIAL
    // http://developer.android.com/reference/android/os/Build.html#SERIAL
    // If a user upgrades software or roots their device, there will be a duplicate entry
    String serial = null;
    try {
        serial = android.os.Build.class.getField("SERIAL").get(null).toString();

        // Go ahead and return the serial for api => 9
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    } catch (Exception exception) {
        // String needs to be initialized
        serial = "serial"; // some value
    }

    // Thanks @Joe!
    // https://stackoverflow.com/a/2853253/950427
    // Finally, combine the values we have found by using the UUID class to create a unique identifier
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

Новое (для приложений с рекламой и сервисами Google Play):

Из консоли разработчика Google Play:

Начиная с 1 августа 2014 года, Правила программы Google Play для разработчиков требует использования всех новых загрузок и обновлений приложения для использования рекламного идентификатора в вместо любых других постоянных идентификаторов для любых рекламных целей. Узнать больше

Осуществление

Разрешение:

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

Код:

import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;
...

// Do not call this function from the main thread. Otherwise, 
// an IllegalStateException will be thrown.
public void getIdThread() {

  Info adInfo = null;
  try {
    adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);

  } catch (IOException exception) {
    // Unrecoverable error connecting to Google Play services (e.g.,
    // the old version of the service doesn't support getting AdvertisingId).

  } catch (GooglePlayServicesAvailabilityException exception) {
    // Encountered a recoverable error connecting to Google Play services. 

  } catch (GooglePlayServicesNotAvailableException exception) {
    // Google Play services is not available entirely.
  }
  final String id = adInfo.getId();
  final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
}

Источник / Docs:

http://developer.android.com/google/play-services/id.html http://developer.android.com/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html

Важно:

Предполагается, что рекламный идентификатор полностью заменит существующий использование других идентификаторов в рекламных целях (например, использование ANDROID_ID в Settings.Secure), когда сервисы Google Play доступны. случаи Службы Google Play недоступны, обозначены GooglePlayServicesNotAvailableException вызывается getAdvertisingIdInfo ().

Предупреждение, пользователи могут сбросить:

http://en.kioskea.net/faq/34732-android-reset-your-advertising-id

Я пытался ссылаться на каждую ссылку, по которой я брал информацию. Если вы пропали без вести и должны быть включены, пожалуйста, прокомментируйте!

Идентификатор службы Google Player

https://developers.google.com/instance-id/

327 голосов
/ 11 апреля 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 по-прежнему довольно легко.

Основываясь на рекомендациях 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 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;
    }
}
173 голосов
/ 28 октября 2011

Вот код, который Рето Мейер использовал в презентации Google I / O в этом году, чтобы получить уникальный идентификатор для пользователя:

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;
}

Если вы объедините это со стратегией резервного копирования для отправки предпочтений в облако (также описанной в разговоре Рето , у вас должен быть идентификатор, который привязывается к пользователю и остается после того, как устройство было стерто, или даже заменить. Я планирую использовать это в аналитике в будущем (другими словами, я еще не сделал этого:).

100 голосов
/ 23 июня 2010

Также вы можете рассмотреть MAC-адрес адаптера Wi-Fi. Получено таким образом:

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

Требуется разрешение android.permission.ACCESS_WIFI_STATE в манифесте.

Сообщается о доступности, даже если Wi-Fi не подключен. Если Джо из приведенного выше ответа попробует это на своих многочисленных устройствах, это было бы неплохо.

На некоторых устройствах он недоступен при выключенном Wi-Fi.

ПРИМЕЧАНИЕ: Из Android 6.x возвращается согласованный поддельный mac-адрес: 02:00:00:00:00:00

82 голосов
/ 08 февраля 2012

Здесь довольно полезная информация здесь .

Он охватывает пять различных типов удостоверений личности:

  1. IMEI (только для устройств Android с телефоном; требуется android.permission.READ_PHONE_STATE)
  2. Псевдо-уникальный идентификатор (для всех устройств Android)
  3. Идентификатор Android (может быть нулевым, может изменяться при сбросе настроек, может быть изменен на телефоне с рутом)
  4. WLAN MAC-адрес строка (необходимо android.permission.ACCESS_WIFI_STATE)
  5. BT MAC-адрес строка (устройства с Bluetooth, необходимо android.permission.BLUETOOTH)
48 голосов
/ 06 апреля 2011

В официальном блоге разработчиков Android появилась полная статья на эту тему: Определение установок приложений .

39 голосов
/ 22 декабря 2012

В Google I / O Рето Мейер (Rto Meier) опубликовал исчерпывающий ответ о том, как подойти к этому, что должно отвечать большинству разработчиков, чтобы отслеживать пользователей в различных установках.Энтони Нолан показывает направление в своем ответе, но я решил написать полный подход, чтобы другие могли легко увидеть, как это сделать (мне потребовалось некоторое время, чтобы выяснить детали).

ЭтоПодход даст вам анонимный, безопасный идентификатор пользователя, который будет постоянным для пользователя на разных устройствах (в зависимости от основной учетной записи Google) и во время установки.Основной подход заключается в создании случайного идентификатора пользователя и сохранении его в общих настройках приложений.Затем вы используете агент резервного копирования Google для хранения общих настроек, связанных с учетной записью Google, в облаке.

Перейдем к полному подходу.Во-первых, нам нужно создать резервную копию для наших SharedPreferences с помощью службы резервного копирования Android.Начните с регистрации приложения через http://developer.android.com/google/backup/signup.html.

. Google предоставит вам ключ службы резервного копирования, который необходимо добавить в манифест.Также необходимо указать приложению использовать BackupAgent следующим образом:

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

Затем необходимо создать агент резервного копирования и указать ему использовать вспомогательный агент для общих настроек:

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

Чтобы завершить резервное копирование, вам нужно создать экземпляр BackupManager в своей основной Деятельности:

BackupManager backupManager = new BackupManager(context);

Наконец, создайте ID пользователя, если он еще не существует, и сохраните его в 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;
}

Этот User_ID теперь будет постоянным во всех установках, даже если пользователь перемещает устройство.

Для получения дополнительной информации об этом подходе см. Доклад Рето .

А подробные сведения о реализации агента резервного копирования см. В Резервное копирование данных .Я особенно рекомендую раздел внизу, посвященный тестированию, поскольку резервное копирование не происходит мгновенно, поэтому для тестирования необходимо принудительно создать резервную копию.

35 голосов
/ 24 марта 2011

Я думаю, что это верный способ создания каркаса для уникального идентификатора ... проверьте его.

Псевдо-уникальный идентификатор, который работает на всех устройствах Android. Некоторые устройства не имеют телефона.(например, планшеты) или по какой-то причине вы не хотите включать разрешение READ_PHONE_STATE.Вы по-прежнему можете читать такие сведения, как версия ПЗУ, имя производителя, тип ЦП и другие сведения об оборудовании, которые хорошо подойдут, если вы хотите использовать идентификатор для проверки серийного ключа или других общих целей.Вычисленный таким образом идентификатор не будет уникальным: можно найти два устройства с одинаковым идентификатором (на основе одного и того же оборудования и образа ПЗУ), но изменения в реальных приложениях незначительны.Для этой цели вы можете использовать класс 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

Большинство членов Build являются строками, и мы здесь берем их длину и преобразуем их по модулю в цифру.У нас есть 13 таких цифр, и мы добавляем еще две впереди (35), чтобы иметь тот же идентификатор размера, что и IMEI (15 цифр).Есть и другие возможности, просто взгляните на эти строки.Возвращает что-то вроде 355715565309247.Специального разрешения не требуется, что делает этот подход очень удобным.


(Дополнительная информация: Приведенная выше методика была скопирована из статьи Pocket Magic .)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...