Telegram изъял 70% адресов каналов, которые не проявляли активность год или более (то есть отобрал у них короткое имя, как например моё @clockstackwheels). Дуров заявил, что, дескать, эти адреса принадлежали иранским киберсквоттерам. Хотя, зная его любовь к выдаче желаемого за действительное, могу предположить, что 70% каналов просто были заброшены. И у меня даже есть идеи, почему, но, думаю, вы и сами догадываетесь.
Тем не менее, независимо от истинных причин, чистить неактивные адреса я считаю правильным. Каналы созданы для того, чтобы быть живым фидом какой-то информации. Не обязательно блогом, это может быть даже технический канал с логом вашего CI/CD по работе.
Издание Telegram Info запустило петицию с требованием вернуть эти адреса. Вот что они пишут: Зачастую каналы используются авторами как личные визитные карточки, каталоги, энциклопедии и публичные архивы..
Я тоже так могу: Зачастую микроскопы используются владельцами как подставки для книг, линзы для поджига костра и инструмент забивания гвоздей!.
Думаю, то же самое (экспроприацию адресов) сделали бы с ботами, если бы на платформу ботов не положили огромный болт ещё несколько лет назад.
#web
🚀 Вышел Room 2.8.0
Самая важная (она и единственная) фича свежего релиза - получение SupportSQLiteDatabase, являющегося оберткой над RoomDatabase с SQLiteDriver. Честно, не знаю кому это пригодится, поэтому будет полезно узнать от вас в комментариях практический опыт.
Менее масштабные, но всё же важные изменения:
👉 minSdk подняли с 21 до 23
👉 Добавили поддержку KMP таргетов: watchOS и tvOS
🛠 Исправили баги
#android#jetpack#androidjetpack
⚙️Jetpack Compose 1.11 — стабильный релиз! 🚀
Что нового:
👉 Визуальная отладка переходов Shared Elements
👉 Переработанная поддержка трекпадов — теперь работают как мышь и распознают жесты
👉 Preview Wrappers для более быстрой работы с превью
👉 Host Defaults для KMP-проектов
👉 Testing APIs v2 для корутин
👉 Экспериментальные API: Styles, MediaQuery, Grid, FlexBox
Подробности по каждому пункту — отдельными постами в @compose_broadcast
#Compose#Android#AndroidJetpack
🚀Вышла новая Jetpack библиотека - Security State Provider (пока в статусе Альфа)
Основная цель библиотеки — предоставить действительные (actionable) данные о состоянии безопасности устройства и его компонентов, в частности:
👉 Версии обновляемых компонентов (updateable system components).
👉 Наличие применённых исправлений безопасности (security patches / applied fixes).
👉 Общий “security state” — то есть агрегированное представление безопасности системы.
То есть, библиотека даёт вам API, чтобы “спросить у Android”: насколько актуальна система, есть ли уязвимости, какие компоненты нуждаются в обновлении.
Она не заменяет шифрование/криптографию (как, скажем, security-crypto), но с дополняет стек безопасности: помогает принимать решения на основании состояния платформы.
#android#androidjetpack#безопасность
🤖Вышел Jetpack Window 1.5.0
Что нового:
👉WindowSizeClass появились разделения для больших (Large - от 1200 до 1600) и очень больших (XLarge - более 1600 dp) экранов
👉 Получение WindowMetrics теперь работает с Application Context, а не только с UI Context
👉 Добавили API для автоматического сохранения и восстановления статуса встраивания Activity при перезапуске процесса
👉 Удалили экспериментальное API WindowInsets
#android#androidjetpack#jetpackupdate
🚀Вышел Core SplashScreen 1.2.0
Что нового:
🌙 Добавлен атрибут isLightTheme для тем SplashScreen — можно корректно выбирать оформление под светлую/тёмную тему
🖼 Иконка загрузки теперь корректно подтягивается через AppCompatResources (улучшена поддержка ресурсов и векторных изображений)
👉 Убрали ручное объявление обращения к новым API — теперь всё автоматически моделируется при сборке с AGP ≥ 7.3 и R8 ≥ 3.3
🐘 Для AGP 8.1 и выше — всё работает “из коробки” без дополнительных настроек ⚙️ (рекомендуется обновление до этой версии AGP или выше)
#android#jetpack#androidjetpack#jetpackupdate
🤖Как проверить, какие комбинации фичей поддерживает камера смартфона
Современные смартфоны умеют снимать с HDR, 120 FPS и стабилизацией, но вот какая комбинация этих фич реально доступна — загадка. Например, стабилизация часто работает только при 1080p, а 60 FPS не всегда доступны в 4K.
С выходом Jetpack CameraX 1.5 появилось API GroupableFeature и новые параметры для SessionConfig, которые позволяют из кода проверить, какие функции камера может использовать одновременно.
// Пример проверки неподдерживаемых комбинаций
val unsupportedFeatures =
mutableSetOf<GroupableFeature>()
val appFeatureOptions =
setOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION)
appFeatureOptions
.filterNot { it in currentFeatures }
.filter { featureOption ->
cameraInfo.isFeatureGroupSupported(
SessionConfig(
useCases = useCases,
requiredFeatureGroup =
currentFeatures + featureOption
)
)
}
.forEach { unsupportedFeatures.add(it) }
Так можно заранее отсеять неподдерживаемые сочетания — например, когда HDR и стабилизация не работают вместе при 60 FPS 🎥
Подробнее в статье (EN)
#android#camerax#Jetpack#androidjetpack
🚀Jetpack Telecom 1.1.0 добавил то, чего не хватало VoIP-приложениям с самого начала — историю звонков прямо в системном дайлере.
До этого момента пропущенный звонок в Telegram или любом другом VoIP-приложении требовал переключиться в само приложение, найти вкладку с историей и перезвонить оттуда. Теперь это можно делать прямо из нативного дайлера Android.
Работает через два новых механизма. Первый — интеграция лога звонков. Приложение регистрирует звонки через TelecomManager.addCall, и они автоматически попадают в системную историю. Для обратного звонка нужно зарегистрировать intent-фильтр на TelecomManager.ACTION_CALL_BACK и правильно обработать EXTRA_UUID, который система отдаёт вместе с вызовом. UUID генерирует CallControlScope.getCallId в момент регистрации звонка — его и нужно хранить, чтобы потом разрезолвить детали вызова.
Второй механизм — исключение из лога. Не каждый звонок стоит светить в системной истории, и теперь это явно контролируется через флаг isLogExcluded = true в CallAttributesCompat. Например, эфемерные или приватные звонки можно просто не записывать.
‼️ ВАЖНО: фичи доступны только на Android 16.1 (SDK 36.1) и выше. Кроме того, нативные дайлеры используют package allowlist для контроля того, какие VoIP-приложения отображаются в истории. Роллаут идёт поэтапно, первым подключился Google Meet. Для локального тестирования Google рекомендует Telecom Sample Dialer из platform-samples.
Меня радует сам вектор: Google последовательно закрывает разрыв между VoIP и нативной телефонией. Жаль, что allowlist пока ограничивает возможности сторонних приложений. Печально то, что это делают так поздно, когда звонки не по телефону делают уже 5–10 лет.
🔗 Источник: android-developers.googleblog.com
#Android#Telecom#AndroidJetpack
🚀Google взялась за упрощение Picture‑in‑Picture
PiP на Android долго был зоопарком: разный API на версиях, разный UI‑стейт, много if (SDK_INT…) и бойлерплейта. Новая Jetpack‑библиотека androidx.core:core-pip как раз и создана, чтобы это спрятать: она выравнивает вызовы PiP между версиями Android, даёт единый способ задавать параметры (особенно для видео/плееров), объединяет разрозненные колбэки состояния PiP и уменьшает количество кода за счёт готовых пресетов действий для типовых сценариев.
Требования: обновляем Activity
Чтобы всё это заработало, мало просто подключить core-pip — нужно обновиться до свежей Activity 1.13.0 (пока в альфе). В этой версии есть новые API для отслеживания состояния PiP (PictureInPictureUiStateCompat и слушатели), на которых удобно строить логику поведения UI, когда окно уходит в PiP или, например, «прячется» в угол.
// Пример кода: реагируем на состояние PiP
class PlayerActivity : ComponentActivity() {
private val pipUiStateListener =
Consumer<PictureInPictureUiStateCompat> { state ->
if (state.isStashed) {
/* спрятать контролы плеера */
} else {
/* показать контролы плеера */
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ... инициализация UI / плеера ...
addOnPictureInPictureUiStateChangedListener(pipUiStateListener)
}
override fun onDestroy() {
removeOnPictureInPictureUiStateChangedListener(pipUiStateListener)
super.onDestroy()
}
}
🔗 Подробности про библиотека в документации
#Android#AndroidDev#AndroidJetpack#PIP
🚀 Вышел SavedState 1.4.0 — теперь с поддержкой nullable типов
Saved State — это библиотека Jetpack, которая помогает сохранять и восстанавливать состояние при пересоздании, например из-за изменений конфигурации в Android или при выгрузке процесса системой. Поддерживает Kotlin Multiplatform
Вышел androidx.savedstate:1.4.0, и в этом обновлении основное внимание уделено улучшению API. Ключевое изменение - добавлена нативная поддержка nullable типов в SavedStateRegistryOwner.saved, а также в функциях encodeToSavedState() и decodeFromSavedState() — теперь можно напрямую сохранять и восстанавливать null-значения без костылей.
// Теперь это работает корректно без дополнительных проверок.
var name: String? by savedState(saved = "name", default = null)
#android#jetpack#kotlin#kmp#jetpackupdate#androidjetpack
Вот реальная история, как знание механики работы ViewModel спасло мне вечер 👇
У меня приложение на Compose и Jetpack Navigation 3 (работает на основе состояния Back Stack). Экран «Навигатор файлов» открывает папки рекурсивно: по сути это тот же экран, но с другими данными. Все данные — из одной и той же ViewModel.❗️Баг: при переходе в папку навигация срабатывает, UI не меняется. Современные ИИ подсказали общие вещи, но не помогли — промты, видимо, подвели (тут мне ещё надо прокачать знания) 🙂
Вспомнил ключевой факт про архитектуру:
👉 Все ViewModel живут в ViewModelStore.
👉 В пределах одного ViewModelStoreOwner (Activity/Fragment/NavBackStackEntry) получение ViewModel по умолчанию идёт по типу.
👉 Если нужно несколько экземпляров одного типа на одном owner’е — используем key.
Решение в одну строку — привязать ключ к ViewModel, связанный с текущей папкой:
@Composable
fun FileNavigator(
folderId: Id,
modifier: Modifier = Modifier,
) {
// новый folderId → новый экземпляр ViewModel → новый UI-стейт
val viewModel: FileNavigatorViewModel = viewModel(
key = "files(rootId='$folderId')"
)
// ...
}
Мини-чеклист, если ловите такой баг
👉 Один экран используется повторно с разными параметрами? → Нужен key.
👉 Меняется route, но owner тот же? → key обязателен.
👉 Используете Hilt/Koin? → У этих функций тоже есть параметр key (hiltViewModel(key=...), koinViewModel(key=...)).
👉 key должен детерминированно зависеть от входных данных (например, folderId).
👉 При навигации назад убедитесь, что ViewModel освобождается ожидаемо.
Ещё нюанс - если у вас сложная иерархия графов, проверьте, к какому ViewModelStoreOwner вы реально привязаны.
Рекомендую посмотреть мои видео по теме:
📹Разбор Jetpack Navigation 3
🪙Полный разбор Jetpack ViewModel в Android и Kotlin Multiplatform
#android#compose#androidjetpack#viewmodel#архитектура
🚀Вышел Jetpack WorkManager 2.11.0
Что важного в новой версии:
❗️ minSdk: 23 (Marshmallow). Lollipop (API 21–22) больше не поддерживается.
🎉 Новое API: setRemoteSessionTimeoutMillis() в Configuration.Builder — задаёт время жизни сессии RemoteWorkManager после последнего использования.
class App : Application(), Configuration.Provider {
override fun getWorkManagerConfiguration(): Configuration {
return Configuration.Builder()
// Сколько живёт RemoteWorkManager-сессия после последнего использования
.setRemoteSessionTimeoutMillis(TimeUnit.MINUTES.toMillis(5))
.build()
}
}
🎉 Тестирование: TestDriver.stopRunningWorkWithReason(...) — можно останавливать выполняющуюся работу с указанием причины.
Зачем: удобно эмулировать внешние условия (остановку системой/приложением) и проверять, что код корректно реагирует на «принудительное завершение».
// Arrange
val request = OneTimeWorkRequestBuilder<MyWorker>().build()
WorkManager.getInstance(context).enqueue(request).result.get()
// Act
val testDriver = WorkManagerTestInitHelper.getTestDriver(context)!!
testDriver.stopRunningWorkWithReason(
request.id,
/* reason */ 0 // укажите код причины, например ваш тестовый/константу из проекта
)
// Assert — далее проверяете ожидаемое состояние
🛠 Также сделали исправление багов
#android#jetpack#workmanager#jetpackupdate#androidjetpack
‼️Google отменяет Compose Material Icons
С релизом Compose Material 3 — версии 1.4.0 Google сделала радикальный шаг: библиотека androidx.compose.material.icons исключена из Material3 и больше не рекомендуется к использованию.
Что произошло
👉 Material Icons удалены из актуального релиза Material3 1.4.0
👉 Поддержка библиотеки прекращена
👉 Можно подключить вручную, но это временная мера для тех, кто не успел мигрировать
❌ Основная причина отказа - негативное влияние на скорость сборки. Библиотека Material Icons тащит весь огромный набор иконок. Это ощутимо увеличивает build time крупных Android и Compose Multiplatform проектов.
Google предлагает переходить на Vector Drawable XML в Android или Compose Multiplatform ресурсах. Скачивайте иконки с вкладки Android на странице Material Symbols и храните в ресурсах проекта
Преимущества использования Material Symbole:
✔️ актуальный набор иконок
✔️ минимальный вес и отсутствие лишних зависимостей
✔️ предсказуемое время сборки
✔️ лучший контроль над ресурсами проекта
❗️ Обновлений библиотеки Material Icons не будет!
Источник - официальная документация Android Jepack
Благодарю подписчика Evgeny F. за то, что обратил внимание на изменение.
#Android#AndroidJetpack#Material3#Compose#CMP