Микросмартфон за 100 рублей: Покупаем смартфон 11-летней давности и… пишем под него приложения

—

от автора

image

Размер экрана — краеугольный камень мира современных смартфонов. Кто-то считает, что дисплеи должны становиться только больше, а рамки — меньше, кто-то любит «средние» дисплеи диагональю в 5+», ну а кто-то остаётся ярым поклонником и приверженцем компактных смартфонов с крошечными дисплейчиками. В наше время, купить новый смартфон с относительно небольшим дисплеем за приемлемые деньги почти нереально — самые бюджетные модели будут слишком тормозными для современного пользователя. Некоторое время назад, я купил себе бюджетный крошечный смартфон 2012 года выпуска — Samsung Galaxy Pocket, причём всего за 100 рублей. Конечно же мне захотелось довести его до ума — а доводить пришлось руками и навыками прожженного программера! Какой смартфон можно получить за 100 рублей? Читаем в статье!

Минутка предыстории

С самого появления смартфонов на рынке, весь мир шагал к тотальному увеличению дисплеев и уменьшению рамок. В какой-то момент, большие смартфоны даже получили отдельное название — падфоны или смартпэды. Такой ход событий было не трудно предугадать: ведь производители дисплейных матриц осваивали всё более и более высокие разрешения и предлагали больше вариантов производителям смартфонов.

image

Однако несмотря на всеобщее засилие больших «лопат», в мире всё ещё оставались поклонники маленьких и компактных телефонов, которыми очень удобно пользоваться одной рукой. Сейчас подобные устройства представляют только небольшие бренды, известные достаточно в узких кругах — в основном, их можно купить на маркетплейсах, в обычных салонах связи их не найти. Мне известно о нескольких подобных устройствах, которые сейчас присутствуют на рынке. Первый из них «закос» под iPhone — Soyes XS11:

image

Но тут уж, если честно, хочется назвать такой смартфон не просто компактным, а совсем малюсеньким. На нём вполне удобно выполнять задачи звонилки, но совсем неудобно набирать текст — поэтому под наши задачи, он не особо подходит. Кроме того, эти девайсы работают на базе бюджетного смартфонного железа 6-7 летней давности, поэтому их производительность будет достаточно невысокой по меркам современного пользователя. Конечно же есть и более серьёзные варианты — например, компания Unihertz (да, тот самый продолжатель идей BlackBerry) делает смартфоны Jelly 2: дисплей с диагональю 3″, Helio P61 под капотом и Android 11 на борту. Вот только цена, мягко говоря, кусачая — 18 тысяч рублей на момент написания статьи. Это слишком дорого!

Но если душа прямо таки лежит к компактным смартфонам, почему бы не обратиться к рынку Б/У устройств и не присмотреть что-то из… прошлого десятилетия? А вариантов ведь реально много — тут и LG Optimus L3 (3.2″), и Samsung Galaxy Pocket Neo (2.8″), Samsung Galaxy Star (3″), Samsung Galaxy Fame (3.5″), Samsung Galaxy Young. Все перечисленные девайсы стоят реально копейки — можно купить живой вариант до 400-500 рублей!

image

Я решил взять себе целых два смартфона: Samsung Galaxy Mini и Samsung Galaxy Pocket первого поколения. Оба достались мне в одном лоте за 2.000 рублей (с 20 телефонами) и обошлись мне по сто рублей, причём оба смартфона были рабочими! Чуть позже я докупил отдельно Galaxy Star (250 рублей), Galaxy Fame (250 рублей) и Galaxy Pocket Neo (~400 рублей) для полноты коллекции — вышло совсем недорого. Итак, что за характеристики мы получаем в смартфоне за 100 рублей:

  • Android: 2.3 Gingerbread.
  • Чипсет: Broadcom BCM21553 с одним ядром Cortex-A5 на частоте 832мгц. Видеочип: VideoCore IV, он же использовался в Raspberry Pi.
  • ОЗУ: 256 мегабайт (предположительно — DDR1).
  • Встроенная память: 3 гигабайта + слот для SD.
  • Дисплей: 2.8″, 240×320, емкостной тачскрин.
  • Сеть: Поддержка 2G/3G. Об LTE и речи не идёт.

Выглядит не особо густо, да? И разрешение весьма низкое — большинство софта не запустится, а о клиентах современных сервисов и мечтать не приходится… или приходится?

image

Конечно же шаловливым ручкам захотелось вернуть жизнь этому миниатюрному красавцу и я решил использовать его как второй смартфон — при этом с клиентом ВК и музыкой, которые я запилил сам.

Разработка под старые версии Android

На самом деле, разработка под старые версии Android не особо отличается от современных версий системы. Кое-где приходится костылить, велосипедить и юзать AppCompat для реализации современных фишек на старых версий системы, но, будем честным, подобного и в последних версиях Android достаточно.

Даже сейчас нет никакой проблемы скачать последнюю версию Android Studio, подключить смартфон с включенной отладкой и отлаживать приложение прямо на девайсе — logcat тоже есть. Единственный нюанс — поиск драйверов и ручное закрытие приложений в таскменеджере, если вы деплоите под Android 2.x (Android Studio не умеет сам закрывать приложение, чтобы переустановить пакет).

В целом, за всё время разработки под старые устройства, я пришёл к следующим выводам:

  • Поскольку большинство устройств имеет одно ядро, для плавности интерфейса нужно минимизировать любую работу в фоне.
  • Взаимодействие с современными веб-сервисами может быть осложнено из-за отсутствия поддержки TLS1.2 и устаревших сертификатов (проверка сертификатов легко обходится специальным костылем, а вот TLS — нет).
  • У Android до 3.0 вся отрисовка интерфейса программная и она опять же, будет сказываться на скорости работы фоновых служб. Чем менее интерфейс комплексный, тем лучше.
  • Пушей нет — да, вообще. Однако это ничуть не помешает нам сделать уведомления практически в реальном времени с помощью… очередного костыля!

Допиливаем ВК

Я уже писал клиент ВК в рамках одной из прошлых статей. Теперь нам нужно довести его до ума — подогнать под разрешение экрана и переработать интерфейс для большей удобности, а также добавить недостающие разделы — я тот ещё любитель полистать мемчики, сидя в автобусе.

Честно сказать, вся концепция интерфейса требовала полной переработки — боковое меню банально очень неудобно использовать на подобных устройствах из-за малых размеров каждой строчки. Поэтому я решил не изобретать велосипед, а обратился к дизайнерам Apple и первоисточнику: официальному клиенту ВК для iOS 6, родом из 2012 года!

image

Приложение для Android выглядело +- также в те годы. Видите вкладки с разделами снизу? Они то нам и нужны — это самый удобный способ навигации на таких смартфонах! Накидав макет в layout’е, я приступил к реализации:

image

Изначально мне хотелось, чтобы всё приложение было плавным и анимированным: для этого я обратился к фреймворку анимаций Android. Суть очень простая — это обычный интерполятор значений от a до b за определенный промежуток времени. При этом мы не можем анимировать произвольное свойство — только те, который уже реализованы в системе (переход, поворот, масштабирование, альфа-канал). Более наглядно это можно представить вот так:

Animation anim = new TranslateAnimation(-metrics.widthPixels, 0, 0, 0); anim.setDuration(650 + (id * 150)); view.startAnimation(anim); 

Да, это всё анимация 🙂 Получаем примерно такой результат:

Обратите внимание, что запуск большого количества анимаций будет вызывать перерисовку даже в том случае, если элемент не видно на экране — от чего у нас будут дикие тормоза! Осторожнее с этим.

После этого, я решил доработать раздел с музыкой: я все еще пользуюсь грязными хаками для получения доступа к API музыки, поскольку «левым» клиентам такой возможности не дают. Публично его расписывать не буду, поскольку это скорее всего нелегально, да и сами ребята из ВК об этом знают (но не думаю, что будут применять какие-то санкции по отношению к «маленьким» разработчикам) — но если нужно, пишите в личку, расскажу всю концепцию.

Во первых, мне хотелось добавить возможность скачивать треки на внутреннюю память/флэшку. А во вторых, мне хотелось добавить фоновое воспроизведение — до этого возможность свернуть приложение и послушать музыку уже была, однако Android мог в любой момент прибить окно с музыкой и оставить нас с носом, остаётся только реализация в виде foreground-сервиса:

В Android есть два типа служб: background (фоновые) и foreground (видимые пользователю). Первый тип служб система может прибить когда угодно — например мало памяти или экономия заряда АКБ. А вот второй тип служб система не прибивает практически никогда, поскольку они обозначают выполнение важной операции в фоне — например скачивание файла или обновление системы. Однако у них есть одно ограничение — они должны быть привязаны к собственному уведомлению, которое нельзя закрыть. В процессе реализации возникло еще пару проблем — Wakelock’и (механизм, предотвращающий уход девайса в «сон») и WiFiLock’и (тоже самое, но для WiFi).

@Override     public int onStartCommand(Intent intent, int flags, int startId) {         notificationManager.notify(NOTIFICATION_ID, notification);         startForeground(NOTIFICATION_ID, notification);          return Service.START_NOT_STICKY;     }      public void play(TrackInfo info) {         currTrack = info;          try {             player.reset();              String alternativeUrl = String.format("http://90.156.209.92/audiorelay.php?act=stream&url=%s", URLEncoder.encode(info.mp3Url));              player.setAudioStreamType(AudioManager.STREAM_MUSIC);             player.setDataSource(alternativeUrl);             player.prepareAsync();              wifiLock = wifiManager.createWifiLock("audio:wifiLock");             wifiLock.acquire();             player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);              player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {                 @Override                 public void onPrepared(MediaPlayer mediaPlayer) {                     player.start();                 }             });              player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {                 @Override                 public void onCompletion(MediaPlayer mediaPlayer) {                     wifiLock.release();                 }             });              notificationBuilder.setContentText(info.artist + " - " + info.name);             notification = notificationBuilder.build();             notificationManager.notify(NOTIFICATION_ID, notification);         } catch (IOException e) {             DialogUtils.showNetworkErrorNotify(getApplicationContext(), "Не удалось воспроизвести трек");              e.printStackTrace();         }     }      public TrackInfo getCurrentTrack() {         return currTrack;     }      public MediaPlayer getPlayer() {         return player;     }

Точно таким же способом я реализовал механизм уведомлений — как я уже говорил раньше, пушей на старых смартфонах нет вообще ни в каком виде, поэтому пришлось реализовывать свой механизм «обновления»: каждые 3-5 секунд запрашиваем список последних 5 диалогов с сервера и сравниваем с предыдущим результатом, если есть новые сообщения — создаём нотификацию.

private NotificationCompat.Builder createMessageNotification(String sender, String message) {         Intent mainActivityIntent = new Intent();         mainActivityIntent.setClass(getApplicationContext(), MainActivity.class);          PendingIntent intent = PendingIntent.                 getActivity(getApplicationContext(), 1, mainActivityIntent, PendingIntent.FLAG_UPDATE_CURRENT);          return new NotificationCompat.Builder(getApplicationContext()).                 setContentTitle(sender).                 setContentText(message).                 setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)).                 setContentIntent(intent).                 setAutoCancel(true).                 setSmallIcon(R.drawable.message);     }      private Conversations.Profile findProfileById(Conversations.Root jObj, int id) {         for (Conversations.Profile profile :                 jObj.response.profiles) {             if(profile.id == id)                 return profile;         }          // This code shouldn't be reached         return null;     }      private void attachEventCheckLoop() {         Handler handler = new Handler();          handler.post(new Runnable() {             @Override             public void run() {                 VK.Instance.request("messages.getConversations", new VK.ObjectResponse<Conversations.Root>() {                     @Override                     public void onSuccess(Conversations.Root jObj) {                         if(prevResponse != null) {                             for(int i = 0; i < jObj.response.items.size(); i++) {                                 Conversations.Item srcItem = prevResponse.response.items.get(i);                                 Conversations.Item newItem = jObj.response.items.get(i);                                  if(newItem.last_message.from_id == Integer.parseInt(AppPreferences.getInstance().Data.id))                                     break;                                  if(srcItem.last_message.id != newItem.last_message.id) {                                     String shortMessage = "";                                      if(newItem.last_message.text == null || newItem.last_message.text.length() == 0)                                         shortMessage = "< Вложение >";                                     else                                         shortMessage = newItem.last_message.text;                                      Conversations.Profile profile = findProfileById(jObj, newItem.conversation.peer.id);                                     NotificationCompat.Builder notify =                                             createMessageNotification(profile == null ? "Беседа" : (profile.first_name + " " + profile.last_name), shortMessage);                                      notificationManager.notify(15, notify.build());                                 }                             }                         }                          prevResponse = jObj;                     }                      @Override                     public void onError(int code, String msg) {                      }                 }, Conversations.Root.class, "&count=5&extended=1");                    handler.postDelayed(this, TIME_INTERVAL * 1000);             }         });     }

После этого, я начал рутинную работу по реализации интерфейса для данных с сервера — паблики, друзья, профили, лента и.т.п. В некотором смысле, реализация ленты весьма занимательна: вообще, для очень больших списков существуют т.н виртуализация ListView — это когда ListView отображает только видимый пользователю кусок датасета (набора данных — например, список записей на стене) и на старых версиях Android она доступна. Однако мне было интересно реализовать вариант, который потреблял бы минимальное количество ОЗУ и где я точно знал бы, когда пользователь видит тот или иной фрагмент приложения. Поэтому я реализовал… пагинацию свайпами! Вот так привет из нулевых!

Для этого я использовал GestureDetector — встроенный в систему класс для обнаружения простых жестов — свайпов и.т.п. ВК при запросе ленты отдаёт специальную метку для получения следующей страницы новостей (поскольку она может динамически меняться и нужно хранить её стейт), мы эти метки просто сохраняем и переключаемся по странницам новостей с помощью обычных свайпов вправо-влево:

paginatorGestureDetector = new GestureDetector(Activity, new GestureDetector.OnGestureListener() {             @Override             public boolean onDown(@NonNull MotionEvent motionEvent) {                 return false;             }              @Override             public void onShowPress(@NonNull MotionEvent motionEvent) {              }              @Override             public boolean onSingleTapUp(@NonNull MotionEvent motionEvent) {                 return false;             }              @Override             public boolean onScroll(@NonNull MotionEvent motionEvent, @NonNull MotionEvent motionEvent1, float distX, float v1) {                 float absValue = 20;                 if(Math.abs(distX) > absValue && !isBusy) {                     if(distX < 0)                         goBack();                      if(distX > 0)                         goForward();                      return true;                 }                 return false;             }              @Override             public void onLongPress(@NonNull MotionEvent motionEvent) {              }              @Override             public boolean onFling(@NonNull MotionEvent motionEvent, @NonNull MotionEvent motionEvent1, float v, float v1) {                 return false;             }         });

Выглядит весьма забавно.

Юзабельно ли всё это на деле?

Давайте смотреть, может ли юзать такой смартфон в наши дни. Берём наш девайс в руки, логинимся и оцениваем его производительность «вхолостую».

image

Работает весьма шустренько, учитывая что это бюджетник 2012 года. Как насчет нашего самопального клиента ВК? Смотрим:

Работает весьма бодро. Не сказать что также плавно, как последний айфон, но и совсем плохим результат явно не назвать!

Смартфонный функционал у девайса тоже вполне ничего: 1-2 SIM (в зависимости от версии), нормальная синхронизация контактов с ПК (однако Kies вроде-бы не работает на Windows 10, но есть vcf):

image

Встроенный почтовый клиент продолжает работать без каких либо проблем. Однако настраивать некоторые почтовые сервисы нужно вручную и с помощью «паролей приложений» — напрямую залогинится возможности нет. В случае «покета», придется поставить стоковый клиент из Android 2.3 вручную.

Мультимедийные возможности тоже радуют: встроенный плеер тачвиза мне всегда очень нравился. Есть и настройки эквалайзера.

Единственное, что откровенно подводит — браузер. Последним вариантом осталась Opera Mini 7 — она позволяет смотреть сайты, но не поддерживает динамический контент, только статику. Ну, зайти на википедию или почитать статью на Хабре хватит. Родной браузер уже не в состоянии что либо загрузить 🙁

image

Ну а в общем, производителньость смартфона весьма радует, согласитесь? Нельзя сказать, что он уж слишком тормозной — по крайней мере, современные ультрабюджетные смартфоны (до 4-5 тысяч рублей) зачастую показывают себя гораздо хуже чем и флагманы прошлых лет, и даже бюджетники!

Заключение

И всё таки, я считаю что мне удалось в каком-то смысле вдохнуть новую жизнь в старенький девайс. Если использовать подобный девайс как второй — на случай, если сел основной смартфон, то такой миниатюрный красаввчик может неождианно выручить даже в довольно сложной ситуации. Кроме того, эти смартфоны всеядны к аккумуляторам — достаточно подпаять + и — и они будут работать хоть от BL-4C.

Главная ценность Galaxy Pocket — в его компактных размерах. А поскольку по настоящему дешевых, маленьких и шустрых смартфонов становится всё меньше и меньше, то нам остаётся лишь продлять жизнь моделям прошлых лет! Есть ли в этом смысл и получил ли смартфон новую жизнь? Пишите в комментариях!

image

Клиент ВК можно скачать на 4pda. Там лежит самая последняя версия (для скачивания нужна регистрация на форуме). Если по каким-то причинам не хотите регистрироваться на форуме — я выложил актуальную версию в комментариях.

Эта статья поддерживается командой ITGLOBAL.COM

Мы — первый облачный провайдер в России, а также интегратор, поставщик ИТ-услуг, продуктов, сервисов и разработчик собственного ПО.

• Наш сайт
• Наш блог про виртуализацию и Enterprise IT
• Истории успеха наших клиентов

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

Понравился Galaxy Pocket?

50.86% Да! Такая крошечка… Уже иду шерстить юлито!59
49.14% Нет… Бесполезный девайс в текущих реалиях.57

Проголосовали 116 пользователей. Воздержались 20 пользователей.

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

Что вам нужно от смартфона?

36.57% Кучу всяких приложений: TikTok, YouTube, Discord, Trello, VK, Instagram, Facebook и.т.п49
51.49% Самый минимум: VK, Telegram, YouTube69
11.94% От телефона мне нужно только звонить16

Проголосовали 134 пользователя. Воздержались 13 пользователей.

ссылка на оригинал статьи https://habr.com/ru/articles/759112/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *