Как стать автором
Обновить
201.65

Android *

Пишем под самую популярную мобильную ОС

Сначала показывать
Порог рейтинга

Нужно было быстренько перехватить вызов нативной функции и посмотреть значение переменной в Android приложении. Как то давно использовал для этого замечательную утилиту Frida. Установил на планшет frida-server (root уже был) и клиент на PC, написал классический JS хук, но он не работал:

defineHandler({
  onEnter(log, args, state) {
    conslole.log('decoder_CRC_check()');
  },

  onLeave(log, retval, state) {
    const libc = Module.findBaseAddress('libc.so');
    console.log(hexdump(libc, {
      /* address: ptr('0x1000'), -- to override the base address */
      offset: 0,
      length: 64,
      header: true,
      ansi: true
    }));
  }
});

В консоли лишь получал TypeError: not a function at onEnter (D:\Distrib\Android TV\frida\hook.js:7)

Убил полдня в поисках "чего я делаю не так", при том что и официальная дока и нейронки твердят, что именно так и нужно получать базовый адрес модуля и, при необходимости, функций. Оказалось, во Frida 17 автор полностью удалил некоторые функции (а дока и нейронки еще не обновились):

  • Module.ensureInitialized()

  • Module.findBaseAddress()

  • Module.getBaseAddress()

  • Module.findExportByName()

  • Module.getExportByName()

  • Module.findSymbolByName()

  • Module.getSymbolByName()

  • Туда же статические функции Memory

И теперь надо писать цепочку вызовов:

const lib = Process.findModuleByName("libc.so");
console.log("[*] libc.so loaded at base: " + lib.base);
const funcAddr = lib.findExportByName("decoder_CRC_t_init");

Итог получился такой универсальный скрипт:

Java.perform(function () {
	const System = Java.use("java.lang.System");
    const Runtime = Java.use('java.lang.Runtime');
    const SystemLoadLibrary = System.loadLibrary.overload('java.lang.String');
    const VMStack = Java.use('dalvik.system.VMStack');
    // "ожидание"\перехват динамической загрузки нативных библиотек
    SystemLoadLibrary.implementation = function(library) {
		console.log("Loading dynamic library => " + library);
        const loaded = Runtime.getRuntime().loadLibrary0(
            VMStack.getCallingClassLoader(), library
        );
        if (library.includes("mylibname")) {
            console.log("\n[+] Hooked mylibname");
            // перехватываем только нужную нам
            hookNativeFunc();
        }
        return loaded;
    }	
});

function hookNativeFunc() {
    //тут имя полностью как называется сам файл в ресурсах
	const lib = Process.findModuleByName("libmylibname.so");
    console.log("[*] mylibname.so loaded at base: " + lib.base);
    const funcAddr = lib.findExportByName("decoder_CRC_t_init");
    if (!funcAddr) {
        console.log("[-] Function not found!");
		return;
    }
    console.log("[+] Found decoder_CRC_t_init at: " + funcAddr);
    Interceptor.attach(funcAddr, {
        onEnter: function (args) {
            var result = args[0];
            var inputPtr = args[1];
            var len = args[2].toInt32();
            console.log("\n[+] decoder_CRC_t_init called");
            console.log("    result:    " + result);
            console.log("    inputPtr:  " + inputPtr);
            console.log("    len:       " + len);
        },
        onLeave: function (retval) {
            //нужный адрес массива, например из IDA PRO
            const wordArrayOffset = 0x5B2C04;
            const wordArray = lib.base.add(wordArrayOffset);
			var ptr = new NativePointer(wordArray); // современный вариант чтения
            console.log("[*] 5B2C04 contents:");
            try {
                console.log(hexdump(ptr, {
				  offset: 0,
				  length: 512,
				  header: true,
				  ansi: true
				}));
            } catch (e) {
                console.log("[!] Error reading 5B2C04:", e);
            }
            console.log("Return value:", retval);
        }
    });
}

Запускается так frida -U -f com.android.app -l hook.js

Теги:
+6
Комментарии5

Как ускорить Android-разработку и избавиться от мучительно долгих запусков эмуляторов ради простого теста? 

Ответ — Robolectric — мощный инструмент для UI‑тестирования Android‑кода без эмулятора. 

Позволяет запускать юнит-тесты Android-приложений прямо в JVM, без эмуляторов и физических устройств. Экономия на каждом тестовом прогоне, обратная связь почти мгновенная.

В Android‑комьюнити у Robolectric неоднозначная репутация из‑за трудностей совместимости с другими библиотеками. Но…его почти бесценные возможности пробудили любопытство и желание копнуть глубже и осмыслить этот инструмент. 

Так и родилась статья «Мечтают ли андроиды о Robolectric? Разбираем фреймворк по косточкам» от Павла Нестеренко, нашего Android-разработчика.

Если вы устали ждать, пока эмулятор запустится, и хотите гонять юнит-тесты за секунды прямо в JVM, то рекомендуем статью к прочтению!

Теги:
0
Комментарии0

Save the date: 4 июля встречаемся на Android Meetup!

В программе доклады от спикеров Wildberries & Russ и Альфа-Банка, Q&A-сессия с розыгрышем мерча, нетворкинг и фуршет для классного завершения вечера.

Поговорим о том, как оживить виджеты, подружить Compose с Koin и навигацией, а заодно встроить одно Android-приложение в другое без боли...или с болью:

«Виджеты на Android: это просто?»
Александр Гирев, Android Team Lead продуктовой команды WB Partners

«Compose+Koin+JetpackNavigation: что мы поняли за 2 года»
Арсений Шпилевой, Android-разработчик кор-команды WB Partners

«Интеграция Android-приложений: подходы и лучшие практики»
Абакар Магомедов, главный техлид разработки в Альфа-Банке

Когда: 4 июля 18:00 (сбор гостей с 17:00)
Где: Москва, пространство Весна + онлайн-трансляция

Регистрация уже открыта — присоединяйтесь онлайн или офлайн!

Теги:
0
Комментарии0

Telegram запустил конкурс для разработчиков под Android. Призовой фонд: $50 000. Срок сдачи работ: 11 июля, 23:59 по дубайскому времени (UTC+4). Объявление итогов: июль 2025.

В дополнение к призовым, победитель конкурса сможет присоединиться к команде Telegram в Дубае и зарабатывать 1 миллион долларов в год после вычета налогов.

Задача: Внедрить обновлённый интерфейс профилей в приложение Telegram для Android в строгом соответствии с предоставленным дизайном.

Полные условия конкурсного задания, технические подробности и макеты представлены в отдельном канале платформы.

Теги:
+1
Комментарии0

Вы - начинающий разработчик под Андроид или просто пишете "для себя" и решили отображать динамическую анимацию через SurfaceView. Например, взяв за основу вот этот код или похожий. Вы разместили SurfaceView или его наследника (у меня MySurfaceView) в activity layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activityMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <agalilov.doppler.MySurfaceView
        android:id="@+id/dopplerView"
        android:background="#040947"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="15dp"
        app:layout_constraintBottom_toTopOf="@+id/btnStartStop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnStartStop"
        android:layout_width="118dp"
        android:layout_height="56dp"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:text="@string/start"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/dopplerView" />

</androidx.constraintlayout.widget.ConstraintLayout>

Запускаете приложение и... ничего не работает: SurfaceView не меняется, картинки нет! Ошибок тоже нет, код рисования выполняется впустую.

Я провёл почти всю ночь, разбираясь в причине. Оказалось, для SurfaceView, который размещён внутри другого View, по-умолчанию используется z-order "позади" родительского View. Это поведение, документированное в разных источниках, оказалось для меня неожиданным.

Лечится просто: при инициализации (в конструкторе класса-наследника) SurfaceView устанавливаем setZOrderOnTop(true):

public MySurfaceView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    setZOrderOnTop(true);
    . . .
}

Вот такая история :)

Теги:
+7
Комментарии0

URLCheck: Полезная утилита для инспекции URL на Android

Хочу поделиться находкой, которая многим здесь придется по душе. Каждый из нас хоть раз с недоверием кликал по сокращенной или странной ссылке, присланной в мессенджере или почте. Сколько раз мы неосознанно переходили по ссылкам с кучей UTM-меток и прочего трекающего мусора?

Недавно я наткнулся на утилиту для Android, которая решает эту проблему - URLCheck.

Это не браузер, а приложение-посредник. Вы назначаете его для открытия ссылок по умолчанию, и когда вы кликаете на любую ссылку, вместо того чтобы сразу открыть его в браузере, URLCheck перехватывает его и показывает вам вот такое окно:

Вот несколько любопытных ключевых фич:

  • Очистка от трекеров: Автоматически вырезает из линка весь мусор вроде UTM-меток и параметров отслеживания, используя правила проекта ClearURLs.

  • Сканер VirusTotal: Позволяет в один клик отправить ссылку на проверку в VirusTotal и посмотреть отчет. (Нужен свой бесплатный API-ключ).

  • Раскрытие коротких ссылок: Показывает, куда на самом деле ведет укороченный линк типа bit.ly - зачастую фишинговые ссылки скрываются за укороченными линками, чтобы усложнить блокировки.

  • Проверка по хост-листам: Интегрируется со списками StevenBlack (adware, malware, fakenews и т.д.) и предупреждает, если домен находится в одном из них.

  • Pattern-checker: Для продвинутых - можно настроить свои правила на основе регулярных выражений. Например, автоматически заменять http на https или twitter.com на nitter.net.

  • Полный контроль над линком: Вы можете вручную отредактировать URL, посмотреть историю изменений или просто скопировать/поделиться ей.

И самое главное — приложение с открытым исходным кодом! Настоящий швейцарский нож для тех, кто заботится о своей безопасности и приватности в сети.

Где скачать:

В общем, рекомендую попробовать. Для меня это стало одним из приложений категории "must-have".

Теги:
+4
Комментарии0

Google опубликовала ролик в рамках своей юмористической рекламной кампании Best Phones Forever с «диалогом» между персонифицированными смартфонами Pixel и iPhone. Повествование разворачивается вокруг анонсированных Apple «прорывных» функций iOS 26, которые, по задумке Google, на самом деле уже давно доступны пользователям Pixel.

В видео iPhone перечисляет «новые» возможности операционной системы Apple: перевод сообщений и звонков в режиме реального времени, интеллектуальный отбор вызовов и умное удержание. Выясняется, что аналогичный функционал появился на устройствах Pixel еще пять лет назад, что ставит под сомнение новизну представленных Apple решений.

Теги:
0
Комментарии1

📜 M-V-подставь_свое

Model-View-*** - это шаблоны проектирования
Важное уточнение: это шаблоны проектирования только для presentation слоя, а не для целого приложения

💃 Model
- это как раз та часть приложения о которой мы ближайшее время говорить не будем
Чаще всего ее называют бизнес логикой, но это не совсем верно
Пока, лучше всего воспринимать ее как модель данных которую наше приложение хочет передать пользователю
Причем не важно будет это Ui или API, или что-то другое
MV шаблоны не про frontend, а про то как передать данные клиенту, кем бы он ни был

🖼 View
- это само представление данных пользователю. То, что он по итогу получит
В мире андройд это обычно Activity, Fragment, View или Compose

🪝***
- это какая-то прослойка между моделью данных и их представлением пользователю

Для чего все эти шаблоны вообще придумали?

Дело в том, что View это какой-то вариант отображения данных клиенту 🏐
И часто возникает ситуация, что нужно создать другой вариант отображения ⚽️
Это может быть как бизнес потребность в перекраске кнопок и проведении при этом ab-тестов, 🏀
или желании разработчиков заменить технологию отображения 🏈

Например, у вас было консольное приложение, а вы вдруг захотели сделать для него UI (GitBash|GitUi здравствуйте),
ну или решили заменить Android.View на Compose

Во всех этих случаях нам хочется чем-то разделить саму View и работу с Model, чтобы иметь возможность заменить только View, не трогая ничего другого

В Android, к этому еще добавляется проблема пересоздания View при изменении конфигурации. Когда вы переворачиваете экран (и не только), весь ваш UI просто уничтожается и создается полностью заново. Хотя с точки зрения пользователя это все тот же экран с теми же данными 🫠

Это создает дополнительную потребность отвязать View от остального приложения, чтобы можно было ее подменять прямо в рантайме

Основные шаблоны это MVC, MVP, MVVM и MVI
О них мы и поговорим в следующих постах...

ПС. Посты с большим опережением есть в тг канале из описания профиля

Теги:
+1
Комментарии1

Магазину приложений RuStore исполнилось три года. Количество установок этого приложения на устройствах пользователей превысило 100 млн.

25 мая 2022 года VK при поддержке Минцифры запустила открытое бета‑тестирование отечественного магазина мобильных приложений для Android под названием RuStore.

В начале февраля 2023 года RuStore объявил о завершении этапа бета‑тестирования магазина приложений. Также создатели платформы перевели интерфейс консоли разработчика на английский язык для удобства иностранных издателей и партнёров.

В декабре 2024 года месячная аудитория магазина приложений RuStore составила 50 млн пользователей старше 12 лет по всей России, согласно исследованию Mediascope. Аудитория Xiaomi Mi Store составила 19 млн, Samsung Galaxy Store — 14 млн, HUAWEI AppGallery — 10 млн, рассказали Хабру в пресс‑службе RuStore. А в Минцифры заявили, что RuStore от VK обошёл по числу пользователей в России App Store от Apple.

В VK добавили, что в каталоге RuStore уже более 50 тысяч приложений, доступных на ОС Android, Harmony OS и «Аврора», от разработчиков из 40 стран мира. Также вышли версии RuStore для электронных книг и умных телевизоров, для проекторов, Hi‑Fi‑аудиоплееров, игровых консолей, кассовых терминалов, умных часов.

Теги:
Всего голосов 6: ↑2 и ↓40
Комментарии9

Google I/O 2025: два вечера главных анонсов вместе с Surf

20 и 21 мая — подключайся к нашим стримам по Google I/O. Будем вместе следить за анонсами новинок, делиться первыми впечатлениями и обсуждать всё самое интересное из мира технологий и разработки в прямом эфире.

Смотрим и комментируем:

  • 20 мая (вторник)
    → 20:00 — Google Keynote: все главные анонсы и будущее технологий от Google.

  • 21 мая (среда)
    → 20:00 — What’s new in Android development tools: новинки для Android-разработчиков.
    → 21:00 — What’s new in Flutter: свежие обновления для Flutter-сообщества.

Время указано по Москве. Позже добавим сюда наших спикеров и персональные ссылки на трансляции.

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

Теги:
Рейтинг0
Комментарии0

Android-приложение «Контакты»: работает — не трогай

У многих полей контакта есть типы. Например, у номеров телефонов или адресов электронной почты по умолчанию есть типы «рабочий» и «домашний». Аналитики сказали, что нужно реализовать дополнительные типы и дать пользователю возможность создавать свои. Звучит легко, но на деле оказалось совсем непросто.

Чтобы заменить стандартные типы полей, нужно добавить новую базу данных с доступными типами полей, а также реализовать отображение и возможность выбора поля. Для этого пришлось во многом переписать код редактирования полей контакта, где и без этого логика была непростой. Теперь стало совсем сложно: при добавлении или обновлении поля в contentProvider нужно указывать тип поля, так что мы начали указывать «custom».

После добавления кастомных типов приложение потеряло стабильность, появились кейсы, в которых кастомные типы работали неправильно. Один из них приводил к крашу: база данных не успевала создаваться при открытии интента на редактирование контакта.

Изначальный путь пользователя — это открыть приложение и увидеть список контактов с аватаркой, именем и номером телефона. Пока этот список подгружался на экране, база данных обычно успевала создаться. Но мы не учли, что при открытии интента на редактирование контакта из другого приложения сразу появляется экран редактирования — в этом случае база данных не успевала инициализироваться.

Создание схемы БД и инициализация стандартными значениями происходила в отдельном потоке, так что у нас получилась небольшая гонка потоков. UI готов отобразить экран и идет в БД за данными, но БД не успевает инициализироваться, так что запрос приводил к критической ошибке. Баг воспроизводился при попытке обратиться к БД только при первом холодном запуске на устройстве или после очистки данных, так как здесь приложению приходится заново создавать схему базы данных.

Пришлось опять добавлять костыль: в отдельной корутине ожидать инициализации БД и только потом начинать рисовать экран...

Дмитрий Бражник, старший инженер-программист в департаменте разработки мобильных приложений YADRO, рассказал в статье, как его команда пыталась допилить стандартное AOSP-приложение «Контакты» и к чему они в итоге пришли.

Теги:
Всего голосов 3: ↑2 и ↓1+2
Комментарии0

Хардкодить допоздна? А может, лучше нет, ворк?

>> Регистрация и программа <<

23 апреля в 20:00 приглашаем воронежских разработчиков на неформальный митап. Для тех, кто не сможет прийти офлайн, будет трансляция.

Никаких скриншотов кода на слайдах. Никакого душного обсуждения документации. Поговорим о том, что окружает нас вне работы. Прокачаем софт-скиллы и нетворкинг.

В программе митапа три доклада:

  • Лёша, Android-разработчик Surf — «Дедлайн "вчера": как работать с приоритетами».

    Как рассеивается внимание? Как ставить приоритеты в работе с командой? Когда нужно выносить переписку в звонок, а когда можно обойтись текстом? Ответим на эти и многие другие вопросы про приоритеты в работе и жизни.

  • Дима, Flutter-разработчик Surf — «Тимлид — друг или враг? Или так»?

    Расскажу о роли тимлида, но со стороны нижестоящего сотрудника. Что мне нравится/что не нравится в лиде, что для меня кажется полезным, а смысл чего я не понимаю.

  • Кирилл, iOS-разработчик, наш друг и гость из Una Financial — «Work-life health для IT-шника среднего возраста».

    Поделюсь жизненными проблемами разработчиков и способами их решения. Внимательный слушатель вообще сможет их избежать! Обсудим, как сделать жизнь лучше, повысить её качество. Максимально продлим трудоспособный возраст.

Митап пройдет 23 апреля, в 20:00, в воронежском пространстве «Eventuki»: ул. Фридриха Энгельса, 52.

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

Запись трансляции обязательно сохраним, но если вы из Воронежа, мы очень ждём понетворкать вживую. До встречи 😉

Теги:
Рейтинг0
Комментарии0

Вышло видеоруководство по переводу смартфонов Pixel на GrapheneOS с упором на конфиденциальность, включая настройку ключевых параметров и установку приложений, а также способы работать с сервисами Google Play с отключением трекеров.

Теги:
Всего голосов 3: ↑1 и ↓2+1
Комментарии1

Ближайшие события

Добавлен Room! :)
Ранее я уже делился статьей про Delight SQL Viewer — библиотеку, позволяющую отлаживать SQLDelight-базу данных напрямую внутри вашего Kotlin Multiplatform-приложения. Однако в одном из наших внутренних проектов используется Room Multiplatform и хотелось иметь возможность отладки БД и в нем. Так и появилась вторая версия библиотеки, которая теперь поддерживает и Room, и SQLDelight.

Что делает библиотека?

  • Позволяет просматривать, добавлять, редактировать и удалять записи в базе через удобный UI прямо в приложении.

  • Автоматически добавляет иконку-ярлык для быстрого запуска (Android и iOS).

  • На Desktop ярлыки не поддерживаются. Для запуска интерфейса используйте обычную кнопку или меню в вашем UI.

  • Легко отключается в продакшен-сборках — можно либо не вызывать init, либо подключать stub-модуль вместо основной библиотеки.

Как использовать?

Зависимости (shared/build.gradle.kts)

val isRelease = /* Ваша логика определения релизной сборки */

dependencies {
    if (isRelease) {
        // В релизе – stub, чтобы не вшивать весь отладочный UI.
        api("ru.bartwell.delightsqlviewer:stub:2.0.0")
    } else {
        // В debug – полная функциональность.
        api("ru.bartwell.delightsqlviewer:runtime:2.0.0")
        api("ru.bartwell.delightsqlviewer:core:2.0.0")
        // Выберите, что используете:
        api("ru.bartwell.delightsqlviewer:sqldelight-adapter:2.0.0")
        // или
        // api("ru.bartwell.delightsqlviewer:room-adapter:2.0.0")
    }
}

Инициализация

  • SQLDelight (Android):

    DelightSqlViewer.init(
        object : SqlDelightEnvironmentProvider() {
            override fun getDriver() = sqlDelightDriver
            override fun getContext() = context
        }
    )
  • Room (Android):

    DelightSqlViewer.init(
        object : RoomEnvironmentProvider() {
            override fun getDriver() = roomDatabase
            override fun getContext() = context
        }
    )
  • iOS (пример для SQLDelight):

    let provider = SqlDelightEnvironmentProvider(driver: sqlDriver)
    DelightSqlViewer.shared.doInit(provider: provider, isShortcutEnabled: true)

    Аналогично и для RoomEnvironmentProvider.

    Также, чтобы ярлык корректно работал на iOS, в вашем AppDelegate нужно переопределить методы обработки ярлыков, например:

    class AppDelegate: NSObject, UIApplicationDelegate {
        func application(
            _ application: UIApplication,
            configurationForConnecting connectingSceneSession: UISceneSession,
            options: UIScene.ConnectionOptions
        ) -> UISceneConfiguration {
            return ShortcutActionHandler.shared.getConfiguration(session: connectingSceneSession)
        }
    }

    Или вызовите DelightSqlViewer.shared.launch() в обработчике вашего Shortcut.

  • Desktop:

    DelightSqlViewer.init(
        object : SqlDelightEnvironmentProvider() {
            override fun getDriver() = sqlDelightDriver
        }
    )

Аналогично и для RoomEnvironmentProvider.

Запуск

После инициализации вызов DelightSqlViewer.launch() откроет интерфейс просмотра и редактирования (на Android/iOS можно также запустить через ярлык при долгом тапе на иконку приложения).

Button(onClick = { DelightSqlViewer.launch() }) {
    Text("Open DB Viewer")
}

Итог

Теперь Delight SQL Viewer покрывает оба основных способа хранения данных в мультиплатформенных проектах — SQLDelight и Room Multiplatform. Если нужно быстро проверить содержимое вашей БД или вручную поправить что-то прямо во время тестирования, эта библиотека может сэкономить кучу времени. Ну и, конечно, легко «прячется» в релизе, чтобы никакого отладочного UI не оставалось.

Ссылка на репозиторий: https://github.com/bartwell/delight-sql-viewer

Буду рад фидбэку и вопросам!

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Как устроена мобильная архитектура Авито?

Гость нового выпуска подкаста «Android Broadcast»Александр Бильчук, руководитель юнита мобильной архитектуры Авито. В беседе с Кириллом Розовым Саша делится особенностями работы отдела мобильной архитектуры:

  • как ставятся задачи и требования к их выполнению?

  • как оценить пользу архитектурных решений?

  • как влияют Jetpack Compose, SwiftUI, AI на архитектуру?

  • как вообще прийти к роли мобильного архитектора?

Ответы на эти и другие вопросы вы найдете в видео.

Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.

Теги:
Всего голосов 15: ↑15 и ↓0+17
Комментарии0

Aptoide криво публикует приложения в RuStore

Это перевод с английского языка. В русской версии описания было "обновление не затрагивает РФ"

В общем, мало что сделали это (стащили в свой стор и перезалили в рушку) без разрешения, так еще и криво.

Теги:
Всего голосов 2: ↑0 и ↓2-2
Комментарии0

Сегодня мое приложение "Печать чека НПД" стало "кирпичом". Что случилось ? Налоговая сделала метод апи требующим авторизацию.

https://lknpd.nalog.ru/api/v1/receipt/nomer_inn/id_cheka/json

Вы спросите, так как какая проблема добавить к запросу авторизацию ?

1) Документации на апи нет

2) Проблемы пройти модерацию Google Play после такой доделки

а) Что отвечать на вопрос об афилированности с госорганами. В обоих вариантах чувствую тот еще гиморой

б) Секция персональных данных. Угу. Попробуй ИИ объяснить зачем тебе логин/пароль от чужого сайта

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии3

Как сократить JSON на 74% при 100 элементах?

Важное преимущество SDUI — возможность внедрять изменения без выпуска новых версий приложений. Но это же преимущество есть его недостаток, ведь передача всех данных по сети зависит от качества соединения и увеличивает объём данных. 

Качество связи мы не можем контролировать, а вот уменьшить количество передаваемой информации посредством сокращения JSON, — вполне.

Нам нужна функция, которая могла бы вынести и переиспользовать общую логику. В нашем SDUI уже существует концепция «функций», и их разнообразные реализации, но ни одна из них не умела сокращать JSON, поэтому нужна была новая.

Функция должна брать общую часть и заменять в ней только те части, которые отличаются от элемента к элементу, оставляя остальное неизменным. Подобный подход давно применяется в виде шаблонизации, что и было необходимо реализовать. Идея в том, чтобы взять шаблон и подставлять в него различные значения. В нашем SDUI мы уже умели подставлять значения из других мест, и для этого у нас есть собственный синтаксис.

Детали реализации шаблонизации в статье.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Обнаружены проблемы с отображением Flutter приложений на Snapdragon 8.

https://github.com/flutter/flutter/issues/137002

Проблемы касаются тех приложений, которые используют Impeller (новый графический движок, который пришёл на замену Skia), при его отключении всё становится хорошо.
Проблемы замечены на Samsung Galaxy S22+, Redmagic 10, Honor Magic6 Lite 5G и Honor Porshe Design Magic7 PSR. На всех этих устройствах установлен Snapdragon 8.

Пример глитча:

Теги:
Рейтинг0
Комментарии2

Kotlin Multiplatform на практике: как работать с технологией (видео-туториал)

Выпустили серию видео о базовых аспектах работы с Kotlin Multiplatform, технологией для мультиплатформенной разработки (iOS, Android, Web, Desktop).

KMP позволяет использовать общую кодовую базу для нескольких платформ. Причём мы можем гибко регулировать, какую часть кода делаем общей (например, оставляем нативный UI-слой, а бизнес-логику делаем общей).

Рассказали, как и для чего применять технологию на практике, и как к ней подступиться.

Уже доступны все шесть выпусков туториала:

1. Что из себя представляет технология KMP?

2. Настройка окружения

3. Структура проекта

4. Верстка на SwiftUI

5. Верстка на Compose

6. Сетевой слой

Посмотреть туториал можно здесь:

К каждому выпуску приложен документ с пояснением некоторых терминов и полезными ссылками (см. в описании видео), которые пригодятся при ознакомлении с материалом.

Теги:
Всего голосов 9: ↑9 и ↓0+9
Комментарии0

Вклад авторов