Pull to refresh
0
ГК ITGLOBAL.COM
Рассказываем про Managed IT, облака и ИБ.

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

Level of difficultyMedium
Reading time11 min
Views15K
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", 240x320, емкостной тачскрин.
  • Сеть: Поддержка 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
Истории успеха наших клиентов
Only registered users can participate in poll. Log in, please.
Понравился Galaxy Pocket?
50.86% Да! Такая крошечка… Уже иду шерстить юлито!59
49.14% Нет… Бесполезный девайс в текущих реалиях.57
116 users voted. 20 users abstained.
Only registered users can participate in poll. Log in, please.
Что вам нужно от смартфона?
36.57% Кучу всяких приложений: TikTok, YouTube, Discord, Trello, VK, Instagram, Facebook и.т.п49
51.49% Самый минимум: VK, Telegram, YouTube69
11.94% От телефона мне нужно только звонить16
134 users voted. 13 users abstained.
Tags:
Hubs:
Total votes 30: ↑29 and ↓1+38
Comments34

Articles

Information

Website
itglobal.com
Registered
Founded
Employees
201–500 employees
Location
Россия
Representative
itglobalcom