Собираем показания датчиков
Датчики, следящие за физическими свойствами и состоянием окружающей среды, предоставляют инновационные способы для улучшения мобильных приложений. Наличие в современных телефонах электронных компасов, датчиков равновесия, яркости и близости открывает целый ряд новых возможностей для взаимодействия с устройством, таких как дополненная реальность и ввод данных, основанный на перемещениях в пространстве.
Датчики в Android делятся на несколько категорий: движения, положения и окружающей среды. Ниже перечислены некоторые виды популярных датчиков:
- Акселерометр (TYPE_ACCELEROMETER)
- Гироскоп (TYPE_GYROSCOPE)
- Датчик освещения (TYPE_LIGHT)
- Датчик расстояния (TYPE_PROXIMITY)
- Датчик магнитных полей (TYPE_MAGNETIC_FIELD)
- Барометр (TYPE_PRESSURE)
- Датчик температуры окружающей среды (TYPE_AMBIENT_TEMPERATURE)
- Измеритель относительной влажности (TYPE_RELATIVE_HUMIDITY)
В каждом телефоне может быть свой набор датчиков. В большинстве аппаратов есть — акселерометр и гироскоп.
Каждый из представленных датчиков заслуживает отдельной статьи. Имейте в виду, что существуют устаревшие классы для работы с датчиками, в частности, для датчиков ориентации и температуры.
Необходимо помнить несколько вещей, работая с датчиками:
- Показания бывают очень неровными. Вам нужно использовать какое-то среднее значение показаний, но не переборщить, чтобы приложение оставалось отзывчивым
- Данные приходят неравномерно. Не ждите спокойного, ровного потока данных
- Попробуйте предугадать будущие действия пользователя. Например, если идут данные о начале вращения устройства, можно предугадать следующее движение и подготовиться к нему
На эмуляторе практически невозможно тестировать работу с датчиками, поэтому используйте реальные устройства. В последних версиях эмуляторов список возможностей датчиков расширился. Смотрите в настройках эмулятора раздел Virtual sensors.
За работу с сенсорами отвечает класс SensorManager, содержащий несколько констант, которые характеризуют различные аспекты системы датчиков Android, в том числе:
Тип датчика Ориентация, акселерометр, свет, магнитное поле, близость, температура и т.д. Частота измерений Максимальная, для игр, обычная, для пользовательского интерфейса. Когда приложение запрашивает конкретное значение частоты отсчётов, с точки зрения сенсорной подсистемы это лишь рекомендация. Никакой гарантии, что измерения будут производиться с указанной частотой, нет. Точность Высокая, низкая, средняя, ненадёжные данные.
Типы датчиков
-
— Измеряет ускорение в пространстве по осям X, Y, Z — Новый датчик для измерения температуры (API 14) в градусах Цельсия, который заменил устаревший TYPE_TEMPERATURE
- TYPE_GRAVITY — Трёхосевой датчик силы тяжести. Как правило, это виртуальный датчик и представляет собой низкочастотный фильтр для показаний, возвращаемых акселерометром — Трёхосевой гироскоп, возвращающий текущее положение устройства в пространстве в градусах по трём осям. По другим данным, возвращает скорость вращения устройства по трём осям в радианах в секунду. — Измеряет степень освещённости. Датчик окружающей освещённости, который описывает внешнюю освещённость в люксах. Этот тип датчиков обычно используется для динамического изменения яркости экрана. — Трёхосевой датчик линейного ускорения, возвращающий показатели ускорения без учёта силы тяжести. Это виртуальный датчик, использующий показания акселерометра. — Датчик магнитного поля, определяющий текущие показатели магнитного поля в микротеслах по трём осям.
- TYPE_ORIENTATION — Датчик ориентации. Измеряет повороты, наклоны и вращение устройства. Считается устаревшим — Датчик атмосферного давления (барометр), возвращающий текущее давление в миллибарах. Можно определять высоту над уровнем моря, путём сравнения атмосферного давления в двух точках. Также барометры могут применяться для прогнозирования погоды. — Датчик приближённости, который сигнализирует о расстоянии между устройством и целевым объектом в сантиметрах. Каким образом выбирается объект и какие расстояния поддерживаются, зависит от аппаратной реализации данного датчика, возможно возвращение двух значений — Близко и Далеко. Типичное его применение — обнаружение расстояния между устройством и ухом пользователя для автоматического регулирования яркости экрана или выполнения голосовой команды. — Датчик относительной влажности в виде процентного значения (API 14) — Возвращает положение устройства в пространстве в виде угла относительно оси. Виртуальный датчик, берущий показания от акселерометра и гироскопа. Также может использовать показания датчика магнитного поля
- TYPE_GEOMAGNETIC_ROTATION_VECTOR — альтернатива TYPE_ROTATION_VECTOR. Меньшая точность, но меньший расход батареи. Появился в Android 4.4 (API 19)
- TYPE_POSE_6DOF — ещё одна альтернатива TYPE_ROTATION_VECTOR. Появился в Android 7.0 (API 24)
- TYPE_SIGNIFICANT_MOTION — Появился в Android 4.3 (API 18)
- TYPE_MOTION_DETECT — детектор движения. Появился в Android 7.0 (API 24)
- TYPE_STATIONARY_DETECT — Появился в Android 7.0 (API 24) — датчик для подсчёта количества шагов
- TYPE_STEP_DETECTOR — определение начала шагов
- TYPE_HEART_BEAT — пульс. Появился в Android 7.0 (API 24)
- TYPE_HEART_RATE — сердечная активность. Появился в Android 4.4 (API 20)
- TYPE_LOW_LATENCY_OFFBODY_DETECT — Появился в Android 8.0 (API 26)
Кроме аппаратных датчиков, в устройствах используются виртуальные датчики, которые предоставляют упрощённые, уточнённые или комбинированные показания, используя комбинацию из нескольких аппаратных датчиков. В некоторых случаях этот способ удобнее.
Чтобы получить доступ к сенсорам, нужно вызвать метод getSystemService().
Устройство может включать в себя несколько реализаций одного и того же типа датчиков. Чтобы найти реализацию, используемую по умолчанию, вызовите метод getDefaultSensor() из объекта SensorManager, передавая ему в качестве параметра тип датчика в виде одной из констант, описанных выше.
Следующий фрагмент кода вернёт объект, описывающий гироскоп по умолчанию. Если для данного типа не существует датчика по умолчанию, будет возвращено значение null.
Таблица значений, возвращаемых датчиками
| Тип датчика | Количество значений | Содержание значений | Примечание |
|---|---|---|---|
| TYPE_ACCELEROMETER | 3 | value[0]: ось X (поперечная) value[1]: ось Y (продольная) value[2]: ось Z (вертикальная) |
Ускорение (м/с 2 ) по трём осям. Константы SensorManager.GRAVITY_* |
| TYPE_GRAVITY | 3 | value[0]: ось X (поперечная) value[1]: ось Y (продольная) value[2]: ось Z (вертикальная) |
Сила тяжести (м/с 2 ) по трём осям. Константы SensorManager.GRAVITY_* |
| TYPE_RELATIVE_HUMIDITY | 1 | value[0]:относительная влажность | Относительная влажность в процентах (%) |
| TYPE_LINEAR_ACCELERATION | 3 | value[0]: ось X (поперечная) value[1]: ось Y (продольная) value[2]: ось Z (вертикальная) |
Линейное ускорение (м/с 2 ) по трём осям без учёта силы тяжести |
| TYPE_GYROSCOPE | 3 | value[0]: ось X value[1]:ось Y value[2]: ось Z |
Скорость вращения (рад/с) по трём осям |
| TYPE_ROTATION_VECTOR | 4 | values[0]: x*sin(q/2) values[1]: y*sin(q/2) values[2]: z*sin(q/2) values[3]: cos(q/2) |
Положение устройства в пространстве. Описывается в виде угла поворота относительно оси в градусах |
| TYPE_MAGNETIC_FIELD | 3 | value[0]: ось X (поперечная) value[1]: ось Y (продольная) value[2]: ось Z (вертикальная) |
Внешнее магнитное поле (мкТл) |
| TYPE_LIGHT | 1 | value[0]: освещённость | Внешняя освещённость (лк). Константы SensorManager.LIGHT_* |
| TYPE_PRESSURE | 1 | value[0]: атм.давление | Атмосферное давление (мбар) |
| TYPE_PROXIMITY | 1 | value[0]: расстояние | Расстояние до цели |
| TYPE_AMBIENT_TEMPERATURE | 1 | value[0]: температура | Температура воздуха в градусах по Цельсию |
| TYPE_POSE_6DOF | 15 | см. документацию | |
| TYPE_STATIONARY_DETECT | 1 | value[0] | 5 секунд неподвижен |
| TYPE_MOTION_DETECT | 1 | value[0] | В движении за последние 5 секунд |
| TYPE_HEART_BEAT | 1 | value[0] |
Огласите весь список, пожалуйста!
У класса SensorManager есть метод getSensorList(), позволяющий получить список доступных датчиков на устройстве через константу Sensor.TYPE_ALL и метод getName():
Так как у каждого устройства свой набор датчиков, то результаты будут у всех разными. Ниже приведены скриншоты с эмулятора и с реального устройства. В первом случае вывелось только 5 датчиков, во-втором было гораздо больше — вы видите только ту часть, которая поместилась на экране.

Также можно получить список доступных датчиков конкретного типа. В следующем фрагменте кода будут возвращены объекты Sensor, представляющие собой все доступные датчики давления:
Можно составить сложное условие, которое будет проверять производителя датчика и его версию. Если необходимого датчика не окажется, то выберем альтернативный вариант.
Интерфейс SensorEventListener — отслеживаем показания
Также вам понадобится интерфейс android.hardware.SensorListener. Интерфейс реализован с помощью класса, который используется для ввода значений датчиков по мере их изменения в режиме реального времени. Приложение реализует этот интерфейс для мониторинга одного или нескольких имеющихся аппаратных датчиков.
Интерфейс включает в себя два необходимых метода:
- Метод onSensorChanged(int sensor, float values[]) вызывается всякий раз, когда изменяется значение датчика. Этот метод вызывается только для датчиков, контролируемых данным приложением. В число аргументов метода входит целое, которое указывает, что значение датчика изменилось, и массив значений с плавающей запятой, отражающих собственно значение датчика. Некоторые датчики выдают только одно значение данных, тогда как другие предоставляют три значения с плавающей запятой. Датчики ориентации и акселерометр дают по три значения данных каждый.
- Метод onAccuracyChanged(int sensor,int accuracy) вызывается при изменении точности показаний датчика. Аргументами служат два целых числа: одно указывает датчик, а другое соответствует новому значению точности этого датчика.
Служба датчиков вызывает onSensorChanged() каждый раз при изменении значений. Все датчики возвращают массив значений с плавающей точкой. Размер массива зависит от особенностей датчика. Датчик TYPE_TEMPERATURE возвращает одно значение — температуру в градусах Цельсия, другие могут возвращать несколько значений. Вы можете использовать только нужные значения. Например, для получения сведений только о магнитном азимуте достаточно использовать первое числов, возвращаемое датчиком TYPE_ORIENTATION.
Параметр accuracy, используемый в методах для представления степени точности датчика, использует одну из констант
- SensorManager.SENSOR_STATUS_ACCURACY_LOW. Говорит о том, что данные, предоставляемые датчиком, имеют низкую точность и нуждаются в калибровке.
- SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM. Говорит о средней степени точности датчика и том, что калибровка может улучшить результат.
- SensorManager.SENSOR_STATUS_ACCURACY_HIGH. Показатели датчика точны настолько, насколько это возможно.
- SensorManager.SENSOR_STATUS_UNRELIABLE. Данные, предоставляемые датчиком, недостоверны. Это значит, что датчик необходимо откалибровать, иначе невозможно считывать результаты.
Чтобы получать события, генерируемые датчиками, зарегистрируйте свою реализацию интерфейса SensorEventListener с помощью SensorManager. Укажите объект Sensor, за которым вы хотите наблюдать, и частоту, с которой вам необходимо получать обновления.
После получения объекта вы вызываете метод registerListener() в методе onResume(), чтобы начать получать обновлённые данные, и вызываете unregisteredListener() в методе onPause(), чтобы остановить получение данных. В этом случае датчики будут использоваться только тогда, когда активность видна на экране.
В следующем примере показан процесс регистрации SensorEventListener для датчика приближенности по умолчанию с указанием стандартной частоты обновления:
Класс SensorManager содержит следующие константы для выбора подходящей частоты обновлений (в порядке убывания):
- SensorManager.SENSOR_DELAY_FASTEST — самая высокая возможная частота обновления показаний датчиков;
- SensorManager.SENSOR_DELAY_GAME — частота, используемая для управления играми;
- SensorManager.SENSOR_DELAY_NORMAL — частота обновлений по умолчанию;
- SensorManager.SENSOR_DELAY_UI — частота для обновления пользовательского интерфейса.
Выбранная вами частота необязательно будет соблюдаться. SensorManager может возвращать результаты быстрее или медленней, чем вы указали (хотя, как правило, это происходит быстрее). Чтобы минимизировать расход ресурсов при использовании датчиков в приложении, необходимо пытаться подбирать наиболее низкую частоту.
Динамические датчики
В Android 7.0 Nougat (API 24) появилось понятие динамических датчиков, рассчитанных на платформу Android Things. Датчики могут присоединяться и отсоединяться от платы в любое время.
Для определения доступных динамических датчиков используются методы isDynamicSensorDiscoverySupported(), isDynamicSensor(), getDynamicSensorList().
Момент присоединения или отсоединения датчика от платы можно отслеживать через класс SensorManager.DynamicSensorCallback.
Напоследок стоит упомянуть, что последние версии Android не позволяют получать данные с датчиков в фоне.
Как записать данные GPS в файл?
Уже более суток сижу катаю дипломную работу.
Суть такова, для начала мне нужно снять показания с датчика Акселерометра(это я сделал) и координаты c GPS.
GPS координаты я получил вывел их в texView но вот теперь мне все данные с Акселерометра и GPS логировать в файл.
лог должен происходить каждые 30 сек. Данные Акселерометра я сумел записать в файл. Но вот как данные с GPS записать в файл вообще не доходит что-то. Что только не перепробывал. Может знает кто?
Ниже приложу исходники, заранее спасибо если кто сможет помочь, ибо уже вообще хз как дальше быть. Тупик какой то)
Файл: Как с помощью Python записать (а не перезаписать) данные из базы SQLite в файл lex.txt.
Помогите с разработкой части проекта, пожалуйста! Есть файл db.sqlite в котором таджикские слова.
Как записать в файл данные?
Вот готовый код: #include <iostream> #include <stdlib.h> #include <locale> #include.
Файл. Как записать данные?
Доброго времени суток. просьба помочь с программой. Програма вычисляет корень квадратный в.
Как записать данные в файл
Как записать данные в файл в определенную строку в PHP
Работа с датчиками в Android, или сервис для записи показаний с акселерометра
Год назад, на хабре публиковалась статья «Собираем показания датчиков с Android смартфона», где рассматривался способ получения данных с акселерометра (кстати говоря, есть пост более старый, в котором рассказывается все то же самое). Недавно передо мной была поставлена похожая задача. Необходимо было создать приложение (решил назвать его «Sensor Logger»), записывающее показания с акселерометра в файл в фоновом режиме. В данной статье постараюсь показать, как можно использовать сервисы и намерения, как работать с текстовыми файлами, а также каким образом отправлять данные из сервиса в Activity.
Рассказывать о снятии показаний с датчиков, классах SensorEventListener и SensorManager не вижу особого смысла, т.к. привел выше две статьи, в которых подробно об этом говорится.
Предполагается, что для читателя данный проект будет являться учебным, поскольку для меня он именно таким и являлся. До текущего момента я никогда не писал на Java и не работал с Android SDK.
Как оказалось, не все так просто
В приведенных выше статьях рассматривались примеры, когда показания датчиков снимались в главном Activity. Они оказались лишь отчасти применимыми к моей задаче. Ибо есть ложка дегтя: жизненный цикл Activity. Очевидно, что не удастся записывать в файл данные в фоновом режиме, если этим будет заниматься класс Activity, поэтому, прочитав ряд статей, было решено написать сервис, который и будет заниматься записью показаний датчиков.
Про сервисы в Android
В Android существует класс Service, который позволяет выполнять задачи приложения в фоновом режиме (стоит отметить, что сервис и Activity работают в одном потоке) в то время, когда телефон заблокирован, или приложение свернуто. Сервис не требует наличия UI, но он может передавать информацию в Activity (например для отображения) или другие сервисы.
Запуск сервиса, получение показаний с акселерометра, запись в файл
Рассмотрим процесс запуска сервиса (метод onStartCommand )
При запуске сервиса происходит инициализация объекта типа SensorManager (переменная sm ). Данный класс в Android предназначен для работы с датчиками (об этом можно почитать в приведенных статьях во введении, а также в документации).
На следующем этапе сервис получает имя директории (с помощью Intent — намерения), в которую необходимо записывать файлы с показаниями (в случае не существования таковой, программа создаст необходимую папку) и открывает для записи файл, именем которого являются дата и время запуска сервиса. За генерацию имени файла отвечает метод currentDateToString , возвращающий дату и время в виде строки.
После открытия файла начинаем снимать показания с датчиков.
При изменении состояния какого-либо из датчиков вызывается метод onSensorChanged , внутри которого идет проверка на то, на каком датчике произошло событие, и если это акселерометр, то показания, которые пришли, записываются в файл и оправляются в Activity приложения (создается новое намерение и вызывается функция sendBroadcast ):
В Activity прием сообщений от сервиса реализован при помощи класса BroadcastReciever, который принимает намерения, отправленные с помощью функции sendBroadcast . Рассмотрим метод rec_start из класса Activity:
Объекты button_rec_off, button_rec_on являются объектами класса Button , а x_label, y_label и z_label — TextView .
В данном методе происходит запуск сервиса, инициализация BroadcastReciever и создание фильтра намерений (класс IntentFilter).
Стоит отметить, что в моем коде также предусмотрены методы для остановки процесса записи. Исходный код и *.apk можно скачать в репозитарии. Ссылка ниже.
Как записать показания датчиков смартфона в файл
Работа с датчиками в Android, или сервис для записи показаний с акселерометра
Год назад, на хабре публиковалась статья «Собираем показания датчиков с Android смартфона», где рассматривался способ получения данных с акселерометра (кстати говоря, есть пост более старый, в котором рассказывается все то же самое). Недавно передо мной была поставлена похожая задача. Необходимо было создать приложение (решил назвать его «Sensor Logger»), записывающее показания с акселерометра в файл в фоновом режиме. В данной статье постараюсь показать, как можно использовать сервисы и намерения, как работать с текстовыми файлами, а также каким образом отправлять данные из сервиса в Activity.
Рассказывать о снятии показаний с датчиков, классах SensorEventListener и SensorManager не вижу особого смысла, т.к. привел выше две статьи, в которых подробно об этом говорится.
Предполагается, что для читателя данный проект будет являться учебным, поскольку для меня он именно таким и являлся. До текущего момента я никогда не писал на Java и не работал с Android SDK.
Как оказалось, не все так просто
В приведенных выше статьях рассматривались примеры, когда показания датчиков снимались в главном Activity. Они оказались лишь отчасти применимыми к моей задаче. Ибо есть ложка дегтя: жизненный цикл Activity. Очевидно, что не удастся записывать в файл данные в фоновом режиме, если этим будет заниматься класс Activity, поэтому, прочитав ряд статей, было решено написать сервис, который и будет заниматься записью показаний датчиков.
Про сервисы в Android
В Android существует класс Service, который позволяет выполнять задачи приложения в фоновом режиме (стоит отметить, что сервис и Activity работают в одном потоке) в то время, когда телефон заблокирован, или приложение свернуто. Сервис не требует наличия UI, но он может передавать информацию в Activity (например для отображения) или другие сервисы.
Запуск сервиса, получение показаний с акселерометра, запись в файл
Рассмотрим процесс запуска сервиса (метод onStartCommand )
При запуске сервиса происходит инициализация объекта типа SensorManager (переменная sm ). Данный класс в Android предназначен для работы с датчиками (об этом можно почитать в приведенных статьях во введении, а также в документации).
На следующем этапе сервис получает имя директории (с помощью Intent — намерения), в которую необходимо записывать файлы с показаниями (в случае не существования таковой, программа создаст необходимую папку) и открывает для записи файл, именем которого являются дата и время запуска сервиса. За генерацию имени файла отвечает метод currentDateToString , возвращающий дату и время в виде строки.
После открытия файла начинаем снимать показания с датчиков.
При изменении состояния какого-либо из датчиков вызывается метод onSensorChanged , внутри которого идет проверка на то, на каком датчике произошло событие, и если это акселерометр, то показания, которые пришли, записываются в файл и оправляются в Activity приложения (создается новое намерение и вызывается функция sendBroadcast ):
В Activity прием сообщений от сервиса реализован при помощи класса BroadcastReciever, который принимает намерения, отправленные с помощью функции sendBroadcast . Рассмотрим метод rec_start из класса Activity:
Объекты button_rec_off, button_rec_on являются объектами класса Button , а x_label, y_label и z_label — TextView .
В данном методе происходит запуск сервиса, инициализация BroadcastReciever и создание фильтра намерений (класс IntentFilter).
Стоит отметить, что в моем коде также предусмотрены методы для остановки процесса записи. Исходный код и *.apk можно скачать в репозитарии. Ссылка ниже.
Как получить данные с датчиков Android устройства по сети?
Дома в качестве часов и прогноза погоды используется старый планшет Acer A500, аккумулятор у него отключен, и он постоянно работает от сети. Вопрос есть ли какая-то возможность получать с его датчиков данные по локальной сети. Акселерометр, датчик освещения, температуры и т.д.?
Андроид на нем стоит уже старенький 4.0.
Возможно есть како-то готовый софт который шлет данные в сеть.
Зачем вам акселерометр, если планшет по сути неподвижен?
Датчик температуры если и есть,то он системный, вряд ли получится получить к нему доступ из gui.
Ну и освещение — не у всех планшетах он есть.
Приложение HomeAssistant вроде умеет собирать такие данные, вот только не факт что оно есть на андроид 4, да и сервер всё равно надо..
Не у каждого есть планшет на андроиде 4.0. Вам прямо с этого планшета поискать приложения в плеймаркете будет куда проще, чем кому-либо другому это сделать со своего устройства и потом гадать будет ли это приложение работать на 4.0

Первое приложение на Котлине для Андроид
Всем привет! Месяц назад у меня появилось желание научиться создавать приложения для Андроид. Выбор языка упал на Котлин.
В течении 21 дня с помощью видео курса и паралельно учебника по котлину усиленно изучал язык (в это время находится в больнице на лечении).
Пройдя лечение и вернувшись домой я решил попробовать свои навыки и создал простую игру, потратив на неё один вечер, а точнее три часа.
Внизу представляю её вашему вниманию:
https://disk.yandex.ru/d/C9GXet9vZkfzCw
Интересно узнать ваше мнение, и да, не бойтесь, вирусов там нету, такое мне не под силу, но при желании проверить можно.
Вот пара скринов для тех кто не хочет устанавливать или для владельцев эппл.

Смысл игры простой, обычные камень, ножницы, бумага против компьютера с зарабатываем очков.

Хотелось бы также пообщаться как с новичками в программировании, так и с профессионалами, вообще все это направление мне очень интересно и я хочу развиваться и совершенствоваться в нём.

Три стратегии монетизации мобильного приложения, которые работают в 2019

В прошлом году среднее количество времени взаимодействия пользователя с мобильными приложениями составляло более 3 часов в день. В 2019 аналитики прогнозируют увеличение этой цифры до 5 часов. Это звучит плохо для обывателя, но для разработчика мобильных приложений это значит бОльшие возможности монетизации.
Каждый день в Google Play добавляется 2500 новых приложений, но только 15 из них cмогут похвастаться доходом $4000/мес через год. В 2018 Tinder стал одним из трех самых прибыльных неигровых приложений для Android, ну а рейтинги игровых давно рвет Candy Crush Saga. Самое доходное приложение для iPhone в США по состоянию на апрель 2018 года — это Fortnite, ежедневный доход которого составляет 1,92 млн. долларов США. Значит ли это, что все ниши заняты? Совсем нет.
Покупки пользователей в приложениях превысили 76 млрд долларов в 2018, а в этом году аналитики прогнозируют еще 20% рост. Вопреки жалобам разработчиков, пользователи все-таки тратят деньги в приложениях. 64% пользователей приложений с моделью freemium заявили, что сделали хотя бы одну покупку в приложении.
Сейчас главная метрика для разработчиков — retention rate. Она определяет и лояльность пользователей, и интересность приложения. Здесь разработчики сталкиваются с дилеммой — сохранить лояльность пользователей и монетизировать каждого из них. В этой статье мы рассмотрим способы монетизации приложения, которые не вредят UX и помогут разработчикам сохранить хорошую карму приложения.
Способ 1. Монетизация пользовательских данных
Монетизация неперсональных данных пользователей — стремительно развивающийся “белый” способ монетизации, который служит дополнительным заработком помимо рекламы в приложении.
Неперсональные данные пользователей включают такие параметры:

Кому могут пригодится информация о Bluetooth-подключении или использовании 3G интернета?
Глобальные компании, центры соцопросов и телеоператоры готовы платить за данные о целевой аудитории и чаще всего работают через посредников. Неперсональные пользовательские данные — главный ингредиент для количественных исследований и определения приоритетных направлений развития компаний и улучшений существующих продуктов и услуг.
Важно! Третья сторона никогда не собирает больше данных, чем вы готовы предоставить. Вы сами единоразово настраиваете типы данных о пользователях, которые в дальнейшем будут передаваться компаниям.
У мобильного приложения с 60 000+ DAU, есть два пути монетизации пользовательских данных: передача данных посредникам и прямая передача данных компаниям. Компании обычно не работают с разработчиками напрямую, но если у вас 4+ приложения с общим DAU от 700 000, шанс работать напрямую есть.
Второй вариант — посредники. Крупнейшие в этой сфере Appgrow, Tutela, Accenture. Они предоставляют SDK для монетизации, который идеально матчится с любыми другими SDK, не много весит и не ест батарею телефона.
Как подготовить приложение к монетизации и добавить user consent?
Сам кусок кода с user consent выглядит так:

Для пользователя это будет выглядеть так (если они нажмут кнопку “Согласиться”, то вы автоматически начнете получать доход от их неперсональных данных):

Главные плюсы монетизации данных:
+ Подходит для всех категорий мобильных приложений.
+ Цены за СРМ намного выше, чем в мобильной рекламе.
+ SDK весит всего 50Kb, работает на бекграунде и не влияет на UX.
+ Отсутствие необходимости в постоянной оптимизации.
+ Постоянный ежемесячный доход за каждого пользователя, который согласился передавать свои данные (то есть оплата за пользователя не единоразовая)
Если вы рассматриваете вариант монетизации приложения таким способом, то начните расширять свою пользовательскую базу уже сегодня. Помните, что чем больше DAU, тем выше прибыль. Если нужно прикинуть приблизительный заработок от монетизации данных, этот калькулятор дохода поможет подсчитать возможный доход для приложения (да, он не учитывает тонкие параметры типа гео и данные, которые вы хотите передавать, поэтому погрешность может быть до 20%).
Способ 2. Реклама в приложении: смарт-баннеры, видео и нативная реклама
Я уже упоминала о том, что пользователи проводят в смартфонах и планшетах более 3 часов в день, поэтому не использовать рекламу в приложениях как источник дохода — странно. Но лавры самых успешных приложений и статистика их доходов не дают спать разработчикам-скаммерам, которые клепают приложения-однодневки, добавляя рекламу везде, куда теоретически может кликнуть пользователь.
Но даже если вы не скаммер, а вполне себе приличный разработчик, который хочет сделать все по уму, статистика окупаемости приложений и средние зарплаты разработчиков немного удручают:

Смотря на график и на эту статистику, неудивительно, что только 31% разработчиков мобильных приложений довольны своим доходом. Кажется, что средний доход в 1 500 — 2000 долларов США вполне нормальный для старта, но по факту большую часть дохода разработчики вкладывают в развитие своих приложений, так что на жизнь остается немного.
Благодаря грамотной рекламе в приложении, суммарный доход можно увеличить почти втрое. Тренды в мобильной рекламе неизменны: максимум нативности, UX-френдли вид и ограничение показов рекламы 1 пользователю.
BusinessofApps считают, что доля нативной рекламы к 2020 г. должна занять 63% от общего объема рекламы.

Еще один рекламный формат, который стоит попробовать в приложении — смарт-баннер, который в отличии от обычного баннера автоматически подстраивается под размер и положение экрана.

Видеореклама до сих пор считается самым быстрорастущим форматом и rewarded videos — источник дохода для всех приложений, которые хотят монетизировать пользователей, не раздражая и не отвлекая их.
Отчет IAB за ноябрь 2018 года показал, что в первые шесть месяцев 2018 года расходы на мобильную видеорекламу в США выросли на 61,5% в годовом исчислении.

Схема работы rewarded videos проста: в определенный этап взаимодействия с приложением пользователю предлагают посмотреть рекламное видео в обмен на бонус. Для игрового приложения это может быть подсказка, дополнительная жизнь или виртуальная валюта, а для утилит — подключение премиум фич на 24 часа.
О чем стоит помнить при рекламной монетизации приложения:
1. Перед монетизацией изучите и посчитайте важные метрики и поведение пользователей.
2. Тестируйте разные форматы рекламы: то, что круто работает у других приложений, может не сработать у вас. Меняйте плейсменты, экспериментируйте и анализируйте эффективность.
3.Не запускайте сразу много рекламы — не каждый пользователь это стерпит.
4. Протестируйте рекламную медиацию для максимального эффекта от рекламы.
Пользователи нормально воспринимают рекламу, но не стоит ходить по лезвию, статистика взаимодействий пользователей с приложением заставляет оставаться в тонусе:

Способ 3. Покупки внутри приложений
Самый популярный источник дохода для разработчиков — in-app purchase, проверенная стратегия продажи “фишечек” внутри приложения. В логике приложения важно продумывать этот способ сразу, чтобы не слишком менять приложение после релиза.
В утилитах и играх отлично продаются премиум-функции, подсказки, в играх еще отлично расходится виртуальная валюта, дополнительная жизнь персонажу и все, что можно потратить в пределах или за пределами приложения.
Для того, чтобы покупки внутри приложений продавались хорошо и регулярно, нужно добавить их в логичные и легкодоступные разделы приложения или показывать всплывающим окном тогда, когда пользователь нуждаются в этих предметах больше всего. Важно соблюдать баланс между сложностью приложения и интересом пользователя: если в игре слишком сложный уровень с самого начала, то раздосадованный пользователь скорее удалит ее, чем станет платить.
Главные способы покупок внутри приложения — подписка и freemium. В приложении freemium доступен бесплатный базовый функционал и есть возможность проапгрейдить приложение до премиум-версии. В ноябре Tinder заработал около 37 миллионов долларов, предложив пользователям обновить бесплатное приложение до версий Plus и Gold.
Подписки — это оптимальная стратегия монетизации для фитнес-приложений, потокового видео и аудио, облачных сервисов и онлайн-журналов типа Ad Age. И хотя только 5% пользователей реально покупают в приложении, этого может вполне хватать на жизнь разработчику.
2019 год станет знаковым для приложений, которые привыкли к одному источнику дохода, но он перестал приносить ожидаемую прибыль. Добавляйте новые стратегии монетизации, тестируйте их эффективность и помните о пользователях.
Как выбить из китайцев новую прошивку?

Первая часть – ЗДЕСЬ, все мои посты о сотрудничестве с Китаем – ЗДЕСЬ.
В прошлой части я рассказал о сложностях получения прошивки от китайского поставщика. Для тех, кто только присоединился напомню, что фактически прошивку делает производитель плат. Требования к изменениям от локального бренда отправляются к поставщику, который переводит их на китайский и пересылает дальше. В этой части я расскажу, почему из китайцев так сложно выбить новый релиз ПО.
Везде и всюду китайцы измеряют ситуацию юанем, хороший и уважаемый заказчик – только тот, который заказывает много. Работать даже не по высоким, а нормальным стандартам качества для перспективного заказчика китайцы не будут. Им можно сколько угодно рассказывать про компанию, потенциальные проекты, перспективы сотрудничества. Эту информацию даже никто не станет проверять. Китайская перспектива – это получить деньги в краткосрочный период.
Итак, для небольших заказов китайцам делать прошивку банально не интересно. Особенно, если это осуществляется в рамках поддержки, а не дозаказа на существующую модель. То есть на запрос изменения или исправления ошибок буквально можно получить ответ «задача не является приоритетной». Приоритет повыситься, если на горизонте появится инвойс на новую партию.
Возможно, ситуация была бы несколько иной, если бы производители плат получали бы какое-то вознаграждение за разработку. Но в рамках китайской бизнес-модели работу по программированию никто не оплачивает. Практика сложилась так, что китайский сборщик оплачивает физические платы, а работы по программированию идут «в дополнение» к заказу на «железо». Именно таким является повсеместный стандарт работы. Запрос на дополнительную оплату работы программистов считается «наглостью», «хамством». В большинстве своём, рядовой сборщик, сотрудничающий с локальным брендом, скорее, уйдёт к иному производителю плат, чем будет платить за работы с кодом.
Оплата за программирование не развита на столько, что большинство производителей материнок не могут даже выставить инвойс за услуги по программированию! Они меряют работы только количеством проданных плат, а не загруженностью отдела разработки.

Так, мне нужно было сделать обновление ПО для смартфона на чипсете Qualcomm. Модель была старой, дозаказы не планировались, продавался смартфон не то, чтобы хорошо. Почти весь сток готов был забрать дистрибьютор из Словакии. Но с одним условием – в прошивке должен быть словацкий язык, не чешский, а именно словацкий. Для вашего понимания, для словаков их собственный язык является важнейшим предметом культа (примерно, как для прибалтов). И, несмотря на то, что чешский и словацкий языки отличаются как английский из Лондона и Ливерпуля или русский из Петербурга и Киева, наличие в прошивке только чешского языка было неприемлемо.
На тот момент, мы уже использовали все рычаги влияния – от давления от поставщика, до попыток взломать прошивку. Но исходный код Qualcomm выстоял. Поставщик был готов инвестировать в разработку и свои собственные деньги, однако получал отказ. Мы даже создали переписку, в которую добавили как меня, так и производителя плат, который мог общаться на ломаном английском. Диалог выглядел примерно так:
Я: Нам нужно обновление прошивки с добавлением нового языка. Я понимаю, что модель старая, и что есть сложности. Но мы готовы оплатить это обновление.
Производитель плат: Работы будут выполнены в рамках нового заказа на платы. Когда вы подтвердите заказ?
Я: Мы не планируем размещать заказ. Нам нужно только обновление существующего ПО. Но мы оплатим работы.
Производитель плат: У нас есть требования по минимальному заказу, если нет заказа, наш начальник не разрешает выпускать новые релизы.
Я: А как же поддержка пользователей?!
Производитель плат: Этот случай не имеет отношения к поддержке.
Я: Вы можете попросить начальника посчитать стоимость работ по доработке? Я уверен, что мы сможем заплатить даже больше.
Производитель плат: Начальник говорит, что мы такие услуги без подтверждения заказа не оказываем. Услуги по разработке очень дорогие.
Я: Вы цифру в долларах или юанях назвать сможете? Дорого – это сколько?
Производитель плат: Нам сложно сказать. Мы не занимаемся разработкой без подтверждения заказа. Вы можете оплатить платы, но не забирать их. Минимальный заказ – 1000 штук, начальник согласовал это количество для вас.
То есть мне предложили купить ненужное железо вместо того, чтобы посчитать работы по разработке, так как в этой компании действовал только один вид прайсов!
К счастью, так как мы имели дело с Китаем, решить вопрос удалось – наш поставщик познакомился с разработчиком из фирмы поставщика плат и… дал ему взятку за новую прошивку. Получилось намного дешевле, чем мы думали (в качестве бонуса, разработчик так же предоставил исходные коды). Так что наш сток благополучно уехал в Братиславу. Спасибо за эту работу нам не сказал ни начальник, ни дистрибьютор. От него мы получили лишь одно гневное письмо, что тестировщики нашли в 3-м уровне меню несколько слов на чешском языке, как можно быть такими неграмотными!

Как вы понимаете, качество работ китайских программистов выливается из мотивации. При заказе на железо, софт доводится до уровня удовлетворительного, но доведением до уровня хорошего уже никто не озадачивается. Квалифицированных программистов из-за рубежа к коду не пускают, у китайцев нет ни времени, ни желания на качественную проработку.
Разумеется, наши талантливые ребята заходили и дальше – под напором русских девелоперов защита исходного кода падала, и дальше от модификации их было уже не удержать. Из системы удалялся мусор, проводилась оптимизация, исправлялся перевод и готовилась хорошая сборка. Но когда качественный билд был готов… китайцы отказывались его использовать! По их словам «программное обеспечение, созданное не в их лаборатории, не может гарантировать качественной работы платы в целом и её компонентов в отдельности».
Некоторые производители плат соглашались ставить такое ПО, только после того, как снимали с себя полные гарантийные обязательства по поддержке и обслуживанию плат. Как вы понимаете, соглашаться на это было достаточно боязно. Так что до масс хорошая работа русских программистов редко когда доходила. Были (и есть), конечно, неавторизованные релизы, но они выпускаются локальными брендами на свой страх и риск. Китайцы о таких обновлениях точно ничего не знают.
Только несколько раз нам удавалось получить и полные схемы плат, и исходные коды. Но это были проекты, когда мы полностью оплачивали проектирование плат, заранее прописывая предоставление кодов. В большинстве своём, у локального бренда на такие проекты нет ни времени, ни бюджета.
Исходя из вышесказанного, вы сами можете оценить сложности с релизом нового ПО для устройства локального бренда. Этот процесс действительно непрост и долог. Жалобы пользователей проверяются и консолидируются представителем службы поддержки, дальше они отправляются в Китай, где от продавца устройства после перевода на китайский попадают к производителю плат. Уже после этого с боем начинается работа над обновлением прошивки, в ходе которой очень непросто получить нужный результат.
Если, конечно, начинается. Ведь поставщик плат готов на какие-то телодвижения только после того, как увидит перспективу дополнительного заработка, а работы по программированию в его прайсе отсутствуют как данность.
После этого материала я не предлагаю ни оправдывать, ни жалеть локальные бренды. Я просто описываю ситуацию так, как она есть. Чтобы вы лучше всё понимали и имели перед глазами полную картину происходящего. Сделать прошивку действительно не так сложно, но очень сложно сделать так, чтобы это обновление стало доступным и заработало в рамках сложившейся бизнес-модели.
Android — записывать показания датчика в .txt файл. Пользовательский интерфейс зависает
В принципе, я пытаюсь записать данные датчика в файл .txt на SD-карте.
Он работает отлично, когда я устанавливаю for (int я = 0; i% 2 == 0; я ++), то есть записывает данные в файл .txt каждые 2 выборки.
Но, как показано в этом коде, я изменил 5 на 1, т.е. я хочу, чтобы каждый отдельный образец записывался в файл. Когда я запустил его, пользовательский интерфейс зависает.
Кто-нибудь может помочь мне решить эту проблему?
Можно ли это зафиксировать, создав еще один поток? (Можно ли сказать так?)
Я новичок и, следовательно, только грубо знаю, возможно, проблема связана с проблемой потока.
