Последнее обновление: 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 за публикацию всех наших опций (в этом вопросе о переполнении стека).
Список опций - причины, почему / почему не стоит их использовать:
Электронная почта пользователя - Программное обеспечение
- Пользователь может изменить адрес электронной почты - крайне маловероятно
- API 5+
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
или
- API 14+
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
( Как получить основной адрес электронной почты устройства Android )
Номер телефона пользователя - Программное обеспечение
- Пользователи могут менять номера телефонов - крайне маловероятно
<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/