Некоторым разработчикам может понадобится идентифицировать Android-устройства своих пользователей. Чаще всего это делается не для того чтобы распознать именно девайс, а для определения конкретной установки приложения. Также я встречала несколько кейсов, когда это было необходимо, если у разработчика появлялось несколько приложений и он хотел понимать, что они работают в одной среде.
Гугл говорит, что идентифицировать устройство очень просто. Но мы же говорим об Android:)
Данная статья ориентирована на приложения или библиотеки, которые не хотят привязываться к гугловым сервисам.
Итак, давайте погрузимся в это чудесное приключение по получению уникального идентификатора устройства.
Тут мы видим несколько путей:
- Advertising ID
- IMEI
- MAC-address
- Serial Number
- Android ID
Выглядит пока что не плохо, не так ли? Целых пять способов получить уникальный идентификатор для Android-устройства. Я уверена, что если вы еще пошуршите по сети, то, наверняка, найдете еще парочку других способов, но тут я вынесла самые популярные. Итак, давайте пойдем по порядку.
Advertising ID
Это уникальный для пользователя рекламный идентификатор, предоставляемый службами Google Play. Он необходим для работы рекламы, чтобы Google понимал, какую рекламу можно показывать конкретному пользователю и какая реклама уже была показана с помощью встроенных в приложения рекламных баннеров. А так же это значит, что вы лишитесь этого идентификатора, если ваше приложение будет скачано, к примеру, с Amazon, а помимо этого вам придется втащить в ваше приложение гугловые библиотеки.
dependencies {
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.google.android.gms:play-services:6.5.87'
}
Вывод: мы не идентифицируем устройство во всех случаях.
Но мы же хотим наверняка, верно? Тогда идем дальше.
IMEI
Это международный идентификатор мобильного оборудования, используемый на телефонах стандарта GSM. Номер IMEI используется сетями для идентификации смартфонов и блокировки доступа в сеть украденных или занесенных в черный список девайсов. Но к сожалению с IMEI может возникнуть ряд проблем:
- Возникает ошибка «Invalid IMEI»
- IMEI можно изменить
- Для получения IMEI необходим permission:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String imei = telephonyMgr.getImei();
} else {
String imei = telephonyMgr.getDeviceId();
}
Вывод: мы не идентифицируем устройство во всех случаях и нас еще и могут обмануть:C
MAC-address
Не надежно 100%. Гугл сам об этом говорит, но, к сожалению, я действительно встречала пару приложений, которые полагались на MAC-address устройства. Не делайте так.
It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address.
Serial Number
Считается уникальным серийным номером устройства, который остается с ним до “самого конца”. Получить его можно таким способом:
//Until Android 7.1 (SDK 25)
Build.SERIAL
//Android 8 (SDK 26) ++
Build.getSerial()
А теперь про проблемы. Во-первых, для получения серийного номера потребуется запросить у пользователя разрешение READ_PHONE_STATE, а пользователь может отказать. Во-вторых, серийный номер можно изменить.
Вывод: мы не идентифицируем устройство во всех случаях, мы должны запросить permission у пользователя, которые их подбешивают и нас все еще могут обмануть.
Android ID
— Вот оно! — должны завопить мы. — Решение всех наших бед!
Android ID — это тоже уникальный идентификатор устройства. Представляет из себя 64-разрядную величину, которая генерируется и сохраняется при первой загрузке устройства.
Получить его можно вот так:
Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Казалось бы, такая короткая строчка избавляет нас от головной боли по идентификации устройства. Даже ребята из гугл использую Android_ID для LVL в примере.
И тут наши надежды рушатся и ничто уже не будет прежним. После обновления на Android 8 Android_ID теперь стал уникальным для каждого установленного приложения. Но, помимо этого, гугл ведь заботится о нас, так что приложения, которые были установлены до обновления останутся с прежними одинаковыми идентификаторами, которые гугл сохраняет с помощью специально написанного для этого сервиса. Но если приложение будет удалено, а затем заново установлено — Android_ID будет разным. Для того чтобы это не произошло, нужно использовать KeyValueBackup.
Но этот backup сервис нужно зарегистрировать, еще и package name указать. Более того, в документации написано, что это может не сработать по любой причине. И кто в этом виноват? Да никто, просто вот так.
Общий вывод
Если у вас хороший бекенд, то просто собирайте слепок устройства (установленные приложения, сервисы, любые данные об устройстве, которые можете достать) и сравнивайте параметры уже там, какой-то процент изменений считайте приемлемым.
P.S. Все подборки я публикую как всегда в телеграм канале miproblema, а ссылку можно найти в моем профиле, либо найти в поиске телеграм по названию.
С наступающим:)
Комментарии (26)
APXEOLOG
29.12.2018 12:24А почему-бы не использовать старую добрую регистрацию с логином и паролем? Если пользовать хочет сохранить свои данные у вас на серверах — он зарегистрируется
miproblema Автор
29.12.2018 12:26а если его пароль и логин украдут? да и текст не об этом, а о том, как идентифицировать без вмешательства со стороны пользователя, только по среде, в которой установлено приложение. К тому же к примеру у вас два приложения и у пользователя два разных логина и пароля в них. И есть частый кейс, когда в таком случае нужно понять, что это один и тот же пользователь, а не два разных.
APXEOLOG
29.12.2018 12:38-1а если его пароль и логин украдут?
А если его телефон украдут?
К тому же к примеру у вас два приложения и у пользователя два разных логина и пароля в них. И есть частый кейс, когда в таком случае нужно понять, что это один и тот же пользователь, а не два разных.
Неужели в андроиде нету возможности приложениям коммуницировать друг с другом? А вообще на стороне сервера такие вопросы решаются историей входов с логированием айпи/времени входа.
А если мы говорим совсем серьезно — вы никак не защититесь от мультиакка, если человек захочет этим заниматься. Он и телефон под рутом перепрошьет чтобы все ваши идентификаторы менять и несколько виртуальных девайсов на пк запустит с разными слепками ПО, и что только не сделает. Защиту от мультиакка нужно продумывать не технически, а логически, с точки зрения поведения приложения
miproblema Автор
29.12.2018 12:43А если его телефон украдут?
Его нужно для начала разлочить, а потом войти в приложение, где тоже может быть пароль. И человек скорее всего заметит, что у него украли девайс, у него будет время заблокировать акк.
Неужели в андроиде нету возможности приложениям коммуницировать друг с другом?
Есть, content provider. Можно решить эту проблему таким образом, да. Но если приложение одно и его удалили, потом, когда его вновь поставят нельзя легко понять, что оно на этом девайсе уже было.
А если мы говорим совсем серьезно — вы никак не защититесь от мультиакка, если человек захочет этим заниматься.
Довольно популярное мнение в последнее время:) Действительно, зачем ставить забор, если его можно переехать танком:))APXEOLOG
29.12.2018 12:54Его нужно для начала разлочить, а потом войти в приложение, где тоже может быть пароль. И человек скорее всего заметит, что у него украли девайс, у него будет время заблокировать акк.
А если у него телефон без лока?
Я не говорил, что не нужно ставить забор. Я говорил, что не имеет смысла ставить что-то кроме обычного забора. Для большинства случаев вам хватит этих самых ненадежных идентификаторов. А те случаи которые вы не словите при этом — ну, они у вас возникнут при любом механизме
Sovigod
29.12.2018 12:30+1иногда хочется забанить пользователя так что бы он не возвращался под другими логинами. Тут очень нужно определить девайс точно.
Sabubu
29.12.2018 14:18Возможность отслеживания пользователя после удаления приложения должна отсутствовать по соображениям приватности. Если вы боитесь злоупотреблений, берите плату за регистрацию. Или спрашивайте email.
Sovigod
29.12.2018 14:32Так мне не нужно после удаления. Мне нужно после повторной установки узнать что этот пользователь мне уже знаком.
Если он удалит и не установит — я буду только рад.
email/sms — достать временные в интернете стоит чуть менее чем ничего.
Плата за регистрацию? — без комментариев.Sabubu
29.12.2018 15:30Если пользователь хочет, чтобы вы не могли его узнать, его право на приватность должно иметь приоритет над вашим любопытством. Кстати, закон «О персональных данных» содержит похожие положения.
Sovigod
29.12.2018 15:47Это не любопытство. Пользователь зарегестировался и принял условия пользования моего приложения. И там есть разрешение собирать его ПД с девайса. А кто-то согласился и с GDPR.
Ну и условия использования моего приложения не позволяют им пользоваться приватно. Не устраивают условия — попрошу на выход.
Пользователь может запросить удаление своих ПД у нас в соответствии с законом указанным Вами. И тогда мы их удалим.
Protos
30.12.2018 03:51А есть кстати требования государства по выявлению мошенничества и идентификаторов устройства, если в политике пдн четко прописана цель почему нет?
advance
30.12.2018 04:17Сервис дает знать, что обрабатывает ПД, имеет политику конфидециальности. Если Вы не готовы поделиться данными, то с Вами сервис работать не будет.
Нельзя принудить оказывать услуги тому, кому их оказывать не хотят. За исключением монополии и прочего.
Потому нужды сервиса часто перевешивают нужды пользователя. Особенно когда сервис- один из лидеров и Вам его услуги очень нужны или необходимы.
Sovigod
29.12.2018 12:33>> Но если приложение будет удалено, а затем заново установлено — Android_ID будет разным
Это реально проверяли? В документации по другому написано. Для смены нужен factory reset или смена APK signing keymiproblema Автор
29.12.2018 12:37Проверка производилась на Nexus 5X. Не все приложения привязаны к гугловым сервисам. Использовали factory reset. Так что в любом случае идентифицировать однозначно нельзя.
Garrett
29.12.2018 15:38В принципе это они правильно сделали что Android_ID меняется при Factory Reset, потому что дальше может быть уже другое физ-лицо пользоваться устройством (продан, подарен, и т.д.)
А нельзя ли запросить данные учётки Google привязанной к телефону? Вопрос конечно что делать если учётка не привязана, но там и Google Play Store и сервисов не будет конечно.
khim
30.12.2018 05:50Ну слава богу хоть после Factory Reset ничего нельзя идентифицировать. Иначе вообще бред получается: Factory Reset должен сделать телефон «как новый» и готовый к продаже — а тут кто-то будет знать что и когда я на нём устанавливал. Непорядок.
DmitryKolpo
30.12.2018 21:56+1Дополнение(предостережение) к Advertising ID:
если испольтзовать этот id и в прайваси полиси ничего не указать, то гугл через некоторое время удалит приложение из гугл стора
advance
30.12.2018 03:40Автору спасибо за труд. Тоже решал эту проблему, но у сервиса была регистрация и оставалось ее дополнить данными хардвари.
Мне, как и многим, тоже не нравится идея однозначной идентификации девайса или пользователя по девайсу. Но тут вопросы не к автору, а к бизнесу. Почти всегда подобное- требование заказчика\работодателя. При том не все и не всегда понимают, что это по сути- тоже ПД. А недавние скандалы об утечках показали что бывает с ПД когда их собирают.
Мы, разрабы, в большинстве случаев- люди подневольные. Клиент хочет- мы делаем. Последствия для пользователя нас не касаются.
Мое мнение- если интерес у бизнеса косвенный или статистический, то бизнес будет готов мериться с погрешностями и одного из предложенных способов хватит за глаза.
В ином случае- это к лучшему, что Google не оставили решения этого вопроса.
Sabubu
Получить id очень просто: при первом запуске генерируете случайное число и сохраняете в папку приложения. Вот и id.
Я вообще не понимаю, почему все эти идентификаторы доступны приложениям. Они должны быть с самого начала не доступны, а если приложения на них полагаются, то должны генерироваться фейковые id.
В Линуксе какие-то аппаратные идентификаторы могут быть в /sys или /proc, думаю, на Андроиде так же.
miproblema Автор
А если пользователь удалит приложение? А если пользователь запретит write external storage?
Sabubu
Если он удалит приложение, то, значит, он не хочет пользоваться вашими услугами и вам больше не нужен id его устройства. Писать надо не на внешнюю память, а в личную папку приложения, туда по моему доступ всегда есть.
bessovesti
Когда у приложения есть триальный период, вот тогда и нужно идентифицировать пользователя по уникальным константным меткам, чтоб понимать использовал пользователь пробный период или нет
advance
Для этого есть Play Services. Всё, что за пределами Google Play, существенной прибыли не приносит, потому не критично
advance
Доступ то есть. Но ведь подобное- требования заказчика. Чего хочет или не хочет пользователь не волнует никого