Получить идентификатор устройства 1с
Всем привет! Если вам нужно создать уникальный и стабильный идентификатор Android-устройства для использования внутри приложения, то вы наверняка заметили тот хаос, который присутствует в документации и в ответах на stackoverflow. Давайте рассмотрим, как решить эту задачу в 2020 году. О том, где взять идентификатор, стойкий к переустановкам вашего приложения, и какие могут быть сложности в будущем — в этом кратком обзоре. Поехали!
Зачем нужна идентификация
В последнее время обсуждения конфиденциальности пользовательских данных стремительно набирают популярность. Возможно, это спровоцировано ростом выручки рекламных гигантов. Возможно, под этими обсуждениями скрывается обеспокоенность монополиями, которые идентифицируют пользователей и их устройства. Так, Apple, борясь со слежкой и ограничивая всем разработчикам использование IDFA, в то же самое время нисколько не ограничивает его себе. Что можно сказать точно: процесс идентификации пользователя приложения для разработчиков усложнился.
В задачах, опирающихся на идентификацию, встречаются: аналитика возвратов, персонализация контента и рекламы, предотвращение мошенничества.
Среди последних можно выделить несколько актуальных проблем:
Общие аккаунты в сервисах с платной подпиской или уникальным платным контентом. Только представьте сколько теряют сервисы вроде Netflix или Coursera от того, что пользователи заводят один аккаунт на нескольких человек.
Обе проблемы ведут либо к потере выручки, либо к репутационным потерям. Надежность их решения напрямую зависит от надежности идентификации устройств.
Основные способы идентификации
Использование аппаратных идентификаторов
Устаревший и нежизнеспособный в настоящее время способ. Google хорошо поработала над тем, чтобы закрыть доступ к ним, поскольку они не меняются даже после сброса к заводским настройкам. Среди таких идентификаторов:
В настоящее время они недоступны без явного запроса разрешений. Более того, если приложению нужно ими пользоваться, оно может не попасть в Play Market. Оно должно основным функционалом опираться на эти разрешения, иначе будут трудности с прохождением ревью. Поэтому сейчас эта опция доступна приложениям для работы со звонками или голосовым ассистентам.
Такие идентификаторы не меняются после сброса к заводским настройкам, и здесь кроется неочевидный недостаток: люди могут продавать свои устройства, и в таком случае идентификатор будет указывать на другого человека.
Генерация UUID с первым запуском
Данный способ схож с использованием cookie: создаем файл со сгенерированной строкой, сохраняем его в песочнице нашего приложения (например с помощью SharedPreferences), и используем как идентификатор. Недостаток тот же, что и у cookie — вся песочница удаляется вместе с приложением. Еще она может быть очищена пользователем явно из настроек.
При наличии у приложения разрешений к хранилищу вне песочницы можно сохранить идентификатор где-то на устройстве и постараться поискать его после переустановки. Будет ли в тот момент нужное разрешение у приложения — неизвестно. Этот идентификатор можно использовать как идентификатор установки приложения (app instance ID).
Использование идентификаторов, предоставляемых системой
В документации для разработчиков представлен идентификатор ANDROID_ID. Он уникален для каждой комбинации устройства, пользователя, и ключа, которым подписано приложение. До Android 8.0 идентификатор был общим для всех приложений, после — уникален только в рамках ключа подписи. Этот вариант в целом годится для идентификации пользователей в своих приложениях (которые подписаны вашим сертификатом).
Существует и менее известный способ получить идентификатор общий для всех приложений, независимо от сертификата подписи. При первичной настройке устройства (или после сброса к заводским) сервисы Google генерируют идентификатор. Вы не найдете о нем никакой информации в документации, но тем не менее можете попробовать код ниже, он будет работать (по состоянию на конец 2020 года).
Добавляем строчку в файл манифеста нужного модуля:
И вот так достаем идентификатор:
В коде происходит следующее: мы делаем запрос к данным из определенного ContentProvider-a, что поставляется с сервисами Google. Вполне возможно, что Google закроет к нему доступ простым обновлением сервисов. И это даже не обновление самой операционки, а пакета внутри нее, т.е. доступ закроется с обычным обновлением приложений из Play Market.
Но это не самое плохое. Самый большой недостаток в том, что такие фреймворки, как Xposed, позволяют с помощью расширений в пару кликов подменить как ANDROID_ID, так и GSF_ID. Подменить локально сохраненный идентификатор из предыдущего способа сложнее, поскольку это предполагает как минимум базовое изучение работы приложения.
Создание цифрового отпечатка (fingerprint) устройства
Идея device-fingerprinting не новая, и активно используется в вебе. У самой популярной библиотеки для создания отпечатка — FingerprintJS — 13 тысяч звезд на GitHub. Она позволяет идентифицировать пользователя без использования cookie.
Рассмотрим идею на примере (цифры взяты приблизительные для иллюстрации).
Возьмем ежедневную аудиторию какого-нибудь Android-приложения. Допустим она составляет 4 миллиона. Сколько среди них устройств марки Samsung? Гораздо меньше, примерно 600 тысяч. А сколько среди устройств Samsung таких, что находятся под управлением Android 9? Уже около 150 тысяч. Выделим среди последних такие, что используют сканер отпечатков пальцев? Это множество устройств еще меньше, ведь у многих планшетов нет сканера отпечатков пальцев, а современные модели опираются на распознавание лица. Получим 25000 устройств. Добавляя больше условий и получая больше информации, можно добиться множеств малых размеров. В идеальном случае — с единственным элементом внутри, что и позволит идентифицировать пользователя. Чем больше пользователей можно различить, тем выше энтропия этой информации.
Среди основных источников информации в Android, доступных без пользовательских разрешений, можно выделить аппаратное обеспечение, прошивку, некоторые настройки устройства, установленные приложения и другие.
Обычно всю добытую информацию хешируют, получая цифровой отпечаток. Его и можно использовать в качестве идентификатора.
Из достоинств метода — его независимость от приложения (в отличие от ANDROID_ID), поскольку при одинаковых показаниях с источников отпечатки будут одинаковыми. Отсюда же вытекает первый недостаток — разные устройства с некоторой вероятностью могут иметь одинаковый отпечаток.
Еще одна особенность отпечатка — не все источники информации стабильны. Например, установленные приложения дадут много энтропии. Возьмите устройство друга, и проверьте, одинаков ли у вас набор приложений. Скорее всего — нет, к тому же приложения могут устанавливаться и удаляться почти каждый день.
Таким образом, метод будет работать при правильном соотношении стабильности и уникальности источников энтропии.
Какой метод выбрать
Итак, мы рассмотрели доступные способы идентификации. Какой же выбрать? Как и в большинстве инженерных задач, единственного правильного решения не существует. Все зависит от ваших требований к идентификатору и от требований к безопасности приложения.
Разумный вариант — использовать сторонние решения с открытыми исходниками. В этом случае за изменениями в политике конфиденциальности будет следить сообщество, вовремя поставляя нужные изменения. За столько лет существования проблемы до сих пор нет популярной библиотеки для ее решения, как это есть для веба. Но среди того, что можно найти на android-arsenal, можно выделить две, обе с открытым исходным кодом.
Android-device-identification — библиотека для получения идентификатора. Судя по коду класса, ответственного за идентификацию, используются аппаратные идентификаторы, ANDROID_ID, и цифровой отпечаток полей из класса Build. Увы, проект уже 2 года как не поддерживается, и в настоящий момент скорее неактуален. Но, возможно, у него еще будет развитие.
Fingerprint-android — совсем новая библиотека. Предоставляет 2 метода: getDeviceId и getFingerprint. Первый опирается на GSF_ID и ANDROID_ID, а второй отдает отпечаток, основанный на информации с аппаратного обеспечения, прошивки и некоторых стабильных настроек устройства. Какая точность у метода getFingerprint — пока неясно. Несмотря на это библиотека начинает набирать популярность. Она проста в интеграции, написана на Kotlin, и не несет за собой никаких зависимостей.
В случае, когда импортирование сторонних зависимостей нежелательно, подойдет вариант с использованием ANDROID_ID и GSF_ID. Но стоит следить за изменениями в обновлениях Android, чтобы быть готовым к моменту, когда доступ к ним будет ограничен.
Если у вас есть вопросы или дополнения — делитесь ими в комментариях. А на этом все, спасибо за внимание!
Внешний компонент "1С:Сканер штрихкода" (Native) версия для платформы "1С Предприятие 8.3".
Внешний компонент "1С:Сканер штрихкода" (Native) для платформы "1С Предприятие 8.3" поставляется в составе "Библиотеки подключаемого оборудования" (далее - БПО). "1С:Библиотека подключаемого оборудования для мобильных приложений" (далее - МБПО) и предназначен для использования ТОЛЬКО в их составе. Самостоятельное использование внешнего компонента не предусмотрено. Компонент предназначен для получения данных от оборудования – сканеров штрихкодов (далее – ШК) и передаче их в платформу "1С: Предприятие".
Основные возможности
Внешний компонент "1С:Сканер штрихкода" (Native) (далее – ВК или "1С:Сканер штрихкода") позволяет получать данные от подключенных сканеров штрихкодов и передавать их в платформу "1С:Предприятие". Компонент поддерживает следующие операционные системы (далее – ОС): Windows x32/x64, Linux (x32/x64), Android (arm, arm64, x86, x86_64), MacOS(x64). Компонент поддерживает следующие режимы подключения к сканирующему оборудованию: клавиатурный (все ОС), virtual COM (все ОС), Bluetooth (Android, Mac), Broadcast (Android).
Схема взаимодействия с оборудованием
Клавиатурный режим
Ограничения клавиатурного режима
Преимуществами клавиатурного режима является его доступность. Он является умолчанием практически для всех моделей сканеров и доступен на всех ОС. Также его легко проверить, подключив сканер и считав какой-нибудь ШК в текстовый редактор. Однако у этого режима есть и ограничения. На большинстве современных клавиатур от
80 до 110 клавиш, тем не менее, ШК может кодировать последовательность байт каждый из которых может принимать значения от 0 до 255. Т.е., в общем случае, количества клавиш на клавиатуре недостаточно для того чтобы передать данные любого ШК. Для того чтобы обойти это ограничение некоторые сканеры используют Ctrl+X или Alt+X нотацию, которые поддержаны в ВК "1С:Сканер штрихкода". Однако не все модели сканеров предоставляют такие возможности и в случае "нестандартных" значений байт данных в ШК (как правило, значения байт <32 и >127) либо не передают никаких данных, либо передают их не стандартизованной последовательностью клавиатурных событий. Поэтому, если необходимо работать со штрихкодами, содержащими не латинские символы или каким-либо образом кодированные данные (больничные листы и т.д.), то лучше воспользоваться подключением по COM, если сканер это позволяет.
"Auto CRLF"
Как правило "по умолчанию" сканеры в клавиатурном режиме настроены с суффиксом ‘CR’ (клавиша Enter), но не для всех моделей сканеров это так. Иногда суффиксом может быть ‘LF’ или ‘CRLF’. Для обобщения всех этих случаев в ВК, кроме обычных односимвольных суффиксов, предусмотрен специальный суффикс "Auto CRLF", который обозначает, что последовательность, состоящая из CRLF в любом сочетании считается суффиксом. Это может облегчить работу с настройками для некоторых моделей сканеров.
Окно "Тест"
Для проверки работы со сканером на Windows и Linux, есть возможность воспользоваться встроенным в ВК окном "Тест". Для этого нужно нажать кнопку "Тест устройства" в форме настроек компонента. Внешний вид окна представлен на следующем рисунке.
Окно тест делает попытку подключения всего доступного оборудования с заданными в форме настроек параметрами. После чего можно сканировать различные ШК, данные полученные с них будут отображаться в поле данных. Получаемая от оборудования информация может быть представлена в окне "Тест" в 3-х режимах: "Тестовом", "Рабочем" и "Отладка клавиатуры". "Тестовый" режим показывает данные от оборудования с заменой непечатаемых символов на их названия, а также названия специальных клавиш, если данные получены от клавиатуры.
Также для проверки правильности настроек сканера на форме Тест расположен проверочный ШК, отсканировав который можно понять правильность настройки сканера. В случае если настройки сканера и ВК "1С:Сканер штрихкода" настроены одинаково (совпадают настройки суффикса, префикса и специальных клавиш на сканере и в ВК), то в поле данных будет выведено "Ваш сканер настроен правильно" ("Your scaner configured correctly"). В случае, когда неправильно настроен суффикс и/или префикс будет выведено соответственно "Данные соответствуют проверочным частично."("The data correspond to the verification partly."), "Неверно настроен суффикс"("Suffix configured wrong"), "Неверно настроен префикс"("Prefix configured wrong").
Android Braodcast
Установленные настройки ВК в МБПО на ТСД Атол Smart.Lite
Настройки ТСД Атол Smart.Lite на Broadcast
Свойства
Компонента не содержит свойств.
Методы
Название (алиас) | Параметры | Возвращаемое значение | Описание |
---|---|---|---|
ПолучитьНомерВерсии(GetVersion | - | - | Метод возвращает строку текущей версии компоненты |
ПолучитьОписание (GetDescription) | - | - | Метод возвращает описание компоненты |
ПолучитьОшибку (GetLastError) | - | - | Метод возвращает последнюю ошибку при работе компоненты |
ПолучитьПараметры (GetParameters) | - | - | Метод возвращает XML документ с описанием настроечных параметров компоненты, передаваемых через метод УстановитьПараметр (SetParameter) |
УстановитьПараметр (SetParameter) | - | - | Метод устанавливает значение одного из параметров, список которых может быть получен методом ПолучитьПараметры (GetParameters) |
Подключить (Open) | - | - | Метод подключает устройство |
Отключить (Close) | - | - | Метод отключает устройство |
ТестУстройства (DeviceTest) | - | - | Метод запускает тест устройства |
Настройки ВК
Начиная с 10-ой редакции драйвера "1С: Сканер штрихкодов" большинство настроек драйвера унифицировано и может быть представлено следующей таблицей. Различия составляют только специфические моменты, связанные с особенностями конкретной ОС.
Название параметра
RU/EN
Возвращаемые события
В случае успешного получения данных от устройства компонента кодирует их соответствующим образом (Строка, Base64) и передает в 1С:Предприятие в виде одного из следующих событий:
Некоторым разработчикам может понадобится идентифицировать Android-устройства своих пользователей. Чаще всего это делается не для того чтобы распознать именно девайс, а для определения конкретной установки приложения. Также я встречала несколько кейсов, когда это было необходимо, если у разработчика появлялось несколько приложений и он хотел понимать, что они работают в одной среде.
Гугл говорит, что идентифицировать устройство очень просто. Но мы же говорим об Android:)
Данная статья ориентирована на приложения или библиотеки, которые не хотят привязываться к гугловым сервисам.
Итак, давайте погрузимся в это чудесное приключение по получению уникального идентификатора устройства.
Тут мы видим несколько путей:
- Advertising ID
- IMEI
- MAC-address
- Serial Number
- Android ID
Advertising ID
Это уникальный для пользователя рекламный идентификатор, предоставляемый службами Google Play. Он необходим для работы рекламы, чтобы Google понимал, какую рекламу можно показывать конкретному пользователю и какая реклама уже была показана с помощью встроенных в приложения рекламных баннеров. А так же это значит, что вы лишитесь этого идентификатора, если ваше приложение будет скачано, к примеру, с Amazon, а помимо этого вам придется втащить в ваше приложение гугловые библиотеки.
Вывод: мы не идентифицируем устройство во всех случаях.
Но мы же хотим наверняка, верно? Тогда идем дальше.
Это международный идентификатор мобильного оборудования, используемый на телефонах стандарта GSM. Номер IMEI используется сетями для идентификации смартфонов и блокировки доступа в сеть украденных или занесенных в черный список девайсов. Но к сожалению с IMEI может возникнуть ряд проблем:
- Возникает ошибка «Invalid IMEI»
- Для получения IMEI необходим permission:
Вывод: мы не идентифицируем устройство во всех случаях и нас еще и могут обмануть: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
Считается уникальным серийным номером устройства, который остается с ним до “самого конца”. Получить его можно таким способом:
А теперь про проблемы. Во-первых, для получения серийного номера потребуется запросить у пользователя разрешение READ_PHONE_STATE, а пользователь может отказать. Во-вторых, серийный номер можно изменить.
Вывод: мы не идентифицируем устройство во всех случаях, мы должны запросить permission у пользователя, которые их подбешивают и нас все еще могут обмануть.
Android ID
— Вот оно! — должны завопить мы. — Решение всех наших бед!
Android ID — это тоже уникальный идентификатор устройства. Представляет из себя 64-разрядную величину, которая генерируется и сохраняется при первой загрузке устройства.
Получить его можно вот так:
Казалось бы, такая короткая строчка избавляет нас от головной боли по идентификации устройства. Даже ребята из гугл использую Android_ID для LVL в примере.
И тут наши надежды рушатся и ничто уже не будет прежним. После обновления на Android 8 Android_ID теперь стал уникальным для каждого установленного приложения. Но, помимо этого, гугл ведь заботится о нас, так что приложения, которые были установлены до обновления останутся с прежними одинаковыми идентификаторами, которые гугл сохраняет с помощью специально написанного для этого сервиса. Но если приложение будет удалено, а затем заново установлено — Android_ID будет разным. Для того чтобы это не произошло, нужно использовать KeyValueBackup.
Но этот backup сервис нужно зарегистрировать, еще и package name указать. Более того, в документации написано, что это может не сработать по любой причине. И кто в этом виноват? Да никто, просто вот так.
Общий вывод
Если у вас хороший бекенд, то просто собирайте слепок устройства (установленные приложения, сервисы, любые данные об устройстве, которые можете достать) и сравнивайте параметры уже там, какой-то процент изменений считайте приемлемым.
Я рассматриваю IMEI как одну из немногих возможностей для монетизации моего скромного труда. Однозначно идентифицировав устройство, на котором исполняется полезная нагрузка, автором которой являюсь я, собственной персоной, имею право на "введите регистрационный ключ". Ссылку на шифровальщик строк, который я использую как кейген оставлю ниже.
В классическом приложении для андроид результатом работы этой процедуры будет IMEI. С одной оговоркой:
В файле манифеста сначала нужно задекларировать потребность в данных телефона. Пользователь будет уведомлен при установке приложения о том что оно собирается собирать такую информацию. И может отказать приложению в этом.
В самом простом случае для получения IMEI в мобильной платформе нужно написать нативное приложение с соответствующим функционалом, проинсталлировать его на устройство пользователя и запускать его в нужный момент из 1С с возвратом результата работы обратно. Более изящный способ - внешняя компонента для реализации такой, казалось бы, насущной потребности, не столь проста в исполнении по причине того факта, что она как то должна получить разрешение на сами возможности работы с телефонией. Манифест нативного мобильного приложения, встраиваемого во внешнюю компоненту не берётся в расчёт мобильной платформой. Не знаю по каким причинам, да это уже и не важно с приходом Android 10.
Если верить официальной документации от Google по разработке приложений для Android, начиная с 10 версии операционной системы разрешение типа "READ_PHONE_STATE" имеют право запрашивать только системные приложения. И все имеющиеся наработки в данном направлении становятся никому не нужны. Даже я сам на своём собственном телефоне в моих личных целях собственноручно написанным кодом IMEI больше никогда не получу. По крайней мере в Android 10 гарантированно нет.
В результате представляю внешнюю компоненту, которая возвращает в 1С не IMEI, но всё же очень длинный номер, который так же уникален, несменяем и легко доступен. Использую из него первые 15 знаков, и пока этого было достаточно для добрых дел.
Package.zip необходимо загрузить в макет внешней компоненты.
Использование в коде:
Работа компоненты проверена на платформе 8.3.15.59.
И на некоторых телефонах от Samsung, Xiaomi, Motorola, Huawei.
Тестирование на ТСД от SUNMI на базе Android 9, к сожалению выявило невозможность применения данной компоненты. В итоге, малоизвестные китайские версии железа ( а может андроида на этом железе ) могут не давать никаких гарантий.
Читайте также: