Для чего нужны старые android смартфоны на самом деле

Зайчатки разума

Записная книжка айтишника

Для чего нужны старые android смартфоны на самом деле

2020-09-30 00:25:56 — Evgeniy Shumilov

  А теперь немного о нестандартном применении стандартных вещей. У моей маман как-то раз полгода тому отказал телефон (MegaFon Login +). Был он куплен в 2015-м году по акции мегафона за 2500 рублей, кажется. Точнее, по акции он продавался за 3990, а я купил у сотрудника мегафона за 2500. Был разлочен с мегафона, затем в корпусе вырезано было дополнительное отверстие, что позволило получить доступ ко второй симкарте. Мегафон просто взял один китайский OEM телефон с непроизводимым названием, заребрендил прошивку, закрыл один слот пластиковой панелью и выпустил это всё на рынок по рекордно низкой цене. В итоге за свои 2500 рублей телефон проработал 4 с лишним года, после чего у него отказал динамик (он и разговорный и не очень - просто меняется сила звука в зависимости от варианта использования). Для маман был приобретён новый телефон, а мегафон до поры/времени выложен на полку. Ремонтировать это чудо бессмысленно, динамик найти и поставить будет стоить почти столько же, за сколько я весь смартфон приобрёл новым, да и производительность у него уже давно не соответствует требованиям времени. Продать такой старый смартфон, с порядочно подсевшим аккумулятором, да ещё и неработающим динамиком тоже вряд ли получится, а если и получится, то за бесценок. Если за него и дадут, то рублей 500, не больше, да и то очень сомнительно.

  Но кролики - это не только ценный мех. В конце-концов, смартфон - это отличный ёмкостный дисплей, процессор, память и вообще среда выполнения приложений.


  Прикрутил я его в качестве панели управления 3д принтером. Поставил Fully Kiosk Browser и телефон в полноэкранном режиме демонстрировал мне тач интерфейс Octorpint. Дешёво, сердито и принтером пользоваться стало намного удобнее. Но был один нюанс - периодически, раз в день-два телефон терял подключение к вайфай и отказывался подключаться к нему снова самостоятельно, а интерфейс он отображал как раз через wifi. Я вяло пытался эту проблему побороть, но в последние пару дней терпение закончилось и я решил взяться за неё серьёзно.

  Хотелось в первую очередь достичь независимости от стабильности вайфая или как минимум контролировать его переподключения. Но тут я внезапно обнаружил, что прошивка телефона поддерживает Tethering из коробки. Одним словом, телефон умеет раздавать интернет. Но что ещё лучше, поддерживается RNDIS - т.е. режим раздачи интернета по сети, а сеть представляет из себя эмуляцию ethernet подключения через USB. Это просто отлично! Т.е. телефон одновременно и заряжается по USB и по USB умеет притворяться сетевой картой!

   Далее были разбирательства с ADB, чтение форумов, натирание гугла и прочие попытки собрать воедино кусочки разбросанной в разных местах информации. Следующая проблема, с которой я столкнулся - для управления телефоном через USB мне нужно включить режим разработчика и отладку на телефоне. И если режим разработчика сохраняется после перезагрузки, то режим отладки - нет. Сначала я пытался решить проблему через запуск скрипта, включающего ADB через sudo с помощью termux boot - не получилось, так не работает. Но потом я нашёл замечательную статью. Автор решал в числе прочего и мою задачу. Суть проста. Сначала перемонтируем раздел system в режим чтения-записи:

mount -oremount,rw /system

  Потом в директории /system/etc/init/ создаём скрипт init_d.rc со следующим содержанием:

service init_d /system/bin/sh /system/bin/sysinit
    user root
    group root
    disabled
    oneshot
    seclabel u:r:sudaemon:s0

on property:sys.boot_completed=1 && property:sys.logbootcomplete=1
    start init_d

  А далее в /etc/init.d создаём скрипты нужного нам содержания, которые и будут запускаться при загрузке. Цифра в начале имени отражает приоритет запуска. У меня в этой директории были 00banner и 90userinit, я добавил к ним свой 99setadb. У скрипта нужно сменить группу и права запуска:

chgrp shell 99setadb
chmod 755 99setadb

В сам скрипт я добавил как включение отладки, так и режима разработчика (на всякий случай):

#!/system/bin/sh
#
# Turn on adb access
# 

settings put global development_settings_enabled 1
settings put global adb_enabled 1

  Вот и всё, это оказалось довольно несложно, после запуска сразу включен режим отладки и можно выполнять на стороне смартфона команды через adb shell.

  Теперь со стороны моего Orange PI нам нужно запустить скрипт, который выполнит несколько действий:

# включаем режим модема
adb shell su -c 'service call connectivity 33 i32 1'
# ждём, пока система опознает новую сетевую карту и получит 
# для неё настройки по DHCP со стороны смартфона
# (у вас цифра 33 может отличаться, это номер сервиса, ищите в гугле)
# лучше сделать более изящно с while и проверкой, но мне лень. :)
sleep 3
# получаем адрес, который нам выдал смартфон        
IP=`ip a s usb0 | sed '/inet /!d;s/^[ \t]*inet //;s/\/.*//'`
# убираем на одноплатнике маршрут по умолчанию, который прописал 
# смартфон в нашу таблицу маршрутизации, мы ведь не хотим ходить 
# в интернет через смартфон без симкарты и с выключенным вайфаем?
sudo ip r d default via 192.168.42.129 dev usb0 proto dhcp metric 100
# добавляем на смартфоне маршрут до серого адреса одноплатника
# тут роутинг не нужен, это не микротик, в рамках одного хоста 
# это будет работать
adb shell su -c "ip r a 10.11.11.26:5000 via $IP"
# открываем на смартфоне браузер с интерфейсом управления принтером
adb shell am start -a android.intent.action.VIEW -d http://10.11.11.26:5000

Для полноты эффекта лучше установить Fully Kiosk Browser. При первом вызове будет запрос, через что открыть, можно также указать, что всегда нужно открывать адреса с помощью Fully Kiosk Browser.

Что ещё можно улучшить?

Можно выключить wi-fi, ибо он нам уже не нужен. 

adb shell su -c 'svc wifi disable'

Можно к одноплатнику подключить датчик движения и включать дисплей в те моменты, когда рядом кто-то есть. Проверить статус дисплея можно следующим образом:

$ adb shell dumpsys power | grep mWakefulness=
  mWakefulness=Asleep 
# Дисплей включен

$ adb shell dumpsys power | grep mWakefulness=
  mWakefulness=Awake
# Дисплей выключен

А нажатие на кнопку питания можно сделать так:

adb shell input keyevent KEYCODE_POWER

Далее если расположить телефон таким образом, чтобы задняя панель была направлена на модель, то можно получить дополнительный источник освещения в виде вспышки. Скажем, чтобы не включая сам принтер включить вспышку на телефоне и через октопринт посмотреть на распечатанную модель (основной источник освещения принтера у меня запитан параллельно с основным блоком питания и гаснет через 10 минут после окончания печати).Управление всякого рода подсветкой - индикаторами, вспышкой и прочим, лежит обычно в /sys/class/leds/. На других телефонах там есть всё - и подсветка кнопок и вспышка, а на Sony Xperia Ultra, помнится, можно было управлять индикатором уведомлений, он был rgb и в файл, соответствующий имени каждого цвета можно было записать любое значение от 0 до 255. Так что можно было выставить любой из 65536 цветов. Зачем это индикатору уведомлений - без понятия. Тем более, что напрямую из интерфейса самого смартфона с такой тонкостью им было управлять невозможно, либо я просто не нашёл этих настроек. 
Вот содержимое с Xiaomi Mi4:

blue               green          led:flash_1      mmc1::       wled:backlight  
button-backlight   lcd-backlight  led:flash_torch  red          
button-backlight1  led:flash_0    mmc0::           torch-light

Для мегафон логина не нашёл, там только яркость подсветки экрана. Так что прикручу потом освещение на отдельный канал реле. Просто знайте, что для большинства телефонов можно включить вспышку через adb shell -c 'echo 255 > /sys/class/leds/led:flash_torch/brightness'. У вас этот путь может отличаться. 

Плюс можно пользоваться и камерой телефона. Есть отличное приложение - IP Webcam. Оно позволяет через вебинтерфейс настроить кучу параметров, управлять фокусом, получить поток прямо в нужном формате и фактически мы можем использовать тот же самый телефон вместо камеры, которая отдельно будет стоить ещё рублей 600-700. Одна беда - на том же MegaFon Login + автозапуск этого приложения не работает нормально - после старта камера вылетает. Значит, нужно поймать интент запускаемого андроид приложения и потом запустить при необходимости его самостоятельно.

adb logcat | grep -F ActivityManager

Открываем приложение, в консоли несколько раз нажимаем Enter, чтобы отделить текущий поток логов от того, что нам необходимо найти и нажимаем в приложении кнопку "Запустить"

09-29 23:13:49.770   857   875 I ActivityManager: START u0 {act=android.intent.action.MAIN cmp=com.pas.webcam/.Rolling} from uid 10120 on display 0

Вот он, родной. Пытался запустить, но получил стектрейс.

adb shell am start -n 'com.pas.webcam/.Rolling'
Starting: Intent { cmp=com.pas.webcam/.Rolling }
java.lang.SecurityException: Permission Denial: starting Intent { flg=0x10000000 cmp=com.pas.webcam/.Rolling } from null (pid=13398, uid=2000) not exported from uid 10120
....

Тогда проверим, как запускается основной интент приложения.

adb shell am start -n 'com.pas.webcam/.Configuration'
Starting: Intent { cmp=com.pas.webcam/.Configuration }

Отлично. В таком случае можно пойти другим, более долгим путём.

adb shell am start -n 'com.pas.webcam/.Configuration'
sleep 5
adb shell input keyevent KEYCODE_MOVE_END; sleep 0.5
adb shell input keyevent KEYCODE_MOVE_END; sleep 0.5
adb shell input keyevent KEYCODE_ENTER; sleep 0.5

Проверил, работает. Отправка кейкода клавиши END нужна, потому что после первого ListBox получает фокус и только после второго переходит в конец списка к необходимой кнопке. Кстати, информацию о кейкодах можно почерпнуть из официальной документации.

Теперь желательно бы скрыть приложение с глаз долой.

adb shell input keyevent KEYCODE_TAB; sleep 0.5
adb shell input keyevent KEYCODE_DPAD_DOWN; sleep 0.5
adb shell input keyevent KEYCODE_DPAD_DOWN; sleep 0.5
adb shell input keyevent KEYCODE_ENTER; sleep 0.5
adb shell input keyevent KEYCODE_ENTER; sleep 0.5

Эту часть наверное следует вставить до запуска веб интерфейса октопринта. Теперь по локальному адресу, который мы получили ещё в IP= на порту 8080 доступен web интерфейс управления параметрами видеопотока. И аудио оно тоже умеет захватывать. Более того, есть возможность поставить под Win и собрать под Linux драйвера, с помощью которых можно использовать поток с телефона так, будто он идёт с обычной веб камеры, подключенной к вашей локальной машине. Полезная и удобная функция. Если же мы хотим использовать видеопоток в октопринте, то нам нужен mjpeg. Урл на mjpeg потока будет в моём случае тут: http://192.168.42.129:8080/video.

Что ещё осталось? Поднять прокси для видеопотока на октопринте или замапить порт, так как для локальной сети, из которой подключаются к октопринту клиенты, адрес 192.168.42.X будет недоступен, а окторинт просто отдаст тот урл видеопотока, который будет прописан в настройках. Возможно ещё подключить к орандж паю пару микросервоприводов, которые бы позволили управлять позиционированием телефона, чтобы можно было его поворачивать и таким образом менять направление камеры. Ну и смоделировать крепления с учётом расположения сервоприводов...

Кажется, я сегодня немного увлёкся.

Теги: 3d-printing, android-soft, automatization, hardware, pi, shell

comments powered by Disqus