Android 15 ворвался в наши жизни с новым усилением безопасности и удобством разработки. Сёрфер Полина, Android-разработчик в Surf, всё посмотрела, попробовала, проанализировала и теперь расскажет, что же там такого интересного. 

Пристальное внимание создатели 15-й версии уделили защите данных пользователей, в том числе, обновлениям в управлении персональной информацией и создании защищенной зоны Private Space для приложений с дополнительной аутентификацией. 

Ещё одно любопытное нововведение — активная поддержка планшетов и складных устройств, новые API и улучшенные инструменты. В Android Studio теперь можно менять размеры экранов виртуальных устройств — теперь разработка адаптивных приложений станет проще.

Что нового

Контроль использования приложений на переднем дисплее

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

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

Постоянная панель задач

Теперь можно выбрать панель задач для устройств с большими экранами. Она может быть временная или постоянная.

По сути, это укороченная версия обычной панели задач Android, которую можно вывести с помощью «смахивания» в нижней части экрана. А ещё можно сделать так, чтобы она отображалась постоянно. 

Так, четыре приложения доступны с панели задач. Пятая иконка даёт доступ к селектору для быстрого открытия других приложений в режиме разделенного экрана.

Поддержка складных телефонов 

Android 15 улучшил поддержку складных устройств: Samsung Galaxy Z Fold и Motorola Razr. Разработчики ввели новые API и функции, которые позволяют приложениям адаптироваться к различным конфигурациям экрана и переключениям между режимами (подробности ищите в рекомендациях для разработчиков).

Ещё появилась функция непрерывности. Она позволяет автоматически переключаться между внутренним и внешним дисплеем при закрытии и открытии устройства. Когда смартфон складывается, изображение с внутреннего дисплея переводится на внешний.

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

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

Адаптивная вибрация 

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

Зачем это нужно? Чтобы, к примеру, увеличить силу вибрации в шумной обстановке и уменьшить её, когда пользователь находится в тихом месте.

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

Архивирование приложений

Киллер фича Android 15 — архивирование. Оно позволяет сохранять данные приложений без их полного удаления — процесс восстановления более удобным. Эта функция также может быть полезна для управления пространством на устройствах с ограниченной памятью.

Допустим, на вашем устройстве есть старая-добрая GTA: San Andreas. Она весит 2,5 ГБ — это не считая пользовательских данных, которые она собирает. 

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

Вы её удалили, всё отлично. А потом файлы перестали быть вам нужны, и вы снова решаете вернуться в игру. 

Вы её переустанавливаете и... начинате играть с нуля — все ваши достижения, машины, дома в игре — все исчезло. Потому что пользовательские данные удалены. Что делать? Страдать Проходить заново.  

Так вот функция архивирования поможет сохранить эти данные, не удаляя его полностью.

Архивирование позволяет уменьшить «вес» приложения с 2,5 ГБ до 150 МБ.

Управление виджетами

Виджеты теперь становятся неактивными при принудительной остановке приложения.

Предиктивная анимация возврата


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

Мультимедиа

Улучшенное управление HDR

Новые API позволяют разработчикам более точно контролировать параметры HDR, включая насыщенность и динамический диапазон. Это помогает создавать более качественные визуальные эффекты на устройствах с большими экранами.

Разработчики смогут адаптировать параметры воспроизведения в зависимости от способностей устройства. Например, видеоплеер сможет автоматически определять тип экрана (HDR или SDR) и настраивать яркость и контрастность. 

Поддержка динамической громкости 

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

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

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

Режим веб-камеры высокого качества 

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

Расширенные возможности работы с аудио 

Новые API упрощают интеграцию с устройствами MIDI и поддерживают виртуальные MIDI-приложения. 

Теперь музыкальные приложения смогут управлять синтезаторами так же, как если бы они использовали USB-устройства MIDI 2.0.

Частичная демонстрация экрана

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

Поддержка страниц размером 16 КБ


Android 15 теперь поддерживает устройства с 16 КБ страницами памяти. 

Требует пересборки приложений, использующих NDK-библиотеки, для корректной работы на таких устройствах.

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

Поддержка Private Space

Отличия Private Space в Android 15

Характеристика

Android 15

Другие версии Android / Аналоги (например, Samsung)

Степень защиты

Создаёт зашифрованное пространство для приложений и файлов, защищенное дополнительной аутентификацией

Использует сторонние приложения для защиты данных: "Safe Folder" в Google Files

Интеграция в систему

Встроенная функция, доступная без установки сторонних приложений

Часто требует установки сторонних решений для обеспечения аналогичной функциональности

Скрытие пространства

Возможность полностью скрыть Private Space из списка приложений и исключить уведомления

В большинстве случаев скрытие зависит от настроек сторонних приложений

Управление учетными записями

Рекомендуется создание отдельной учетной записи для управления данными

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

Автоматическая блокировка

Возможность настройки автоматической блокировки Private Space после периода бездействия

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

Сохранение данных

Все данные и приложения в Private Space изолированы от основного пространства устройства

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

Новый тип службы переднего плана — mediaProcessing

Этот тип службы подходит для операций типа перекодирования медиафайлов. Службы mediaProcessing могут работать до 6 часов в течение 24-часового периода.

Управление аудиопотоком

При достижении пределов ресурсов все открытые аудиотреки отменяются. Это может повлиять на приложения, которые работают с аудио.

Изменения в поведении служб переднего плана

Введены ограничения на время работы служб dataSync и mediaProcessing — максимум 6 часов за 24 часа. Для корректного завершения служб нужно реализовать метод Service.onTimeout(int, int).

Удаление PNG-формата эмодзи

В Android 15 больше нет старого шрифтп эмодзи (NotoColorEmojiLegacy.ttf), остались только векторные файлы. Придётся адаптировать приложения для использования новых форматов.

Ограничения на запуск служб при получении BOOT_COMPLETED

Новые ограничения запрещают запуск служб приоритета (dataSync, camera и других.) при получении широковещательного сообщения BOOT_COMPLETED.

Рекомендации для разработчиков

Обновление конфигурации сборки

Для использования новых API нужно обновить файл build.gradle:

android {
    compileSdkVersion "35"
    defaultConfig {
        targetSdkVersion "35"
    }
}

Поддерживаемые устройства

  • Pixel 6, 6 Pro, 6a;

  • Pixel 7, 7 Pro, 7a;

  • Pixel Fold, Pixel Tablet;

  • Pixel 8, 8 Pro, 8a;

  • Pixel 9, 9 Pro XL.

Работаем с Android 15

Чтобы начать работать с Android 15, мы можем выбрать один из следующих подходов:

  • установка на устройство Google Pixel;

  • настройка эмулятора Android;

  • получение общего образа системы (GSI).

Установка Android Studio

Для разработки под Android 15 нужно установить последнюю версию Android Studio (Koala Feature Drop | 2024.1.2 или выше)

После — настраиваем SDK:

1. Открываем меню: Инструменты > Диспетчер SDK.
2. Выбираем пакет Android SDK Platform 35.
3. Устанавливаем последнюю версию Build-Tools.

Чтобы реализовать функцию непрерывности в Android 15 в Android Studio, используем новые API. Они помогают адаптировать приложения к конфигурациям экрана и переключениям между режимами. Давайте разберёмся, как реализовать эту функцию.

Реализация функции непрерывности

Адаптивный интерфейс

С помощью Configuration определяем текущее состояние экрана (сложенный или разложенный) и устанавливаем макет.

override fun onConfigurationChanged(newConfig: Configuration) {
	super.onConfigurationChanged(newConfig)
    
	if (newConfig.isScreenWide()) {
    	// Измените макет для широкого экрана
    	setContentView(R.layout.activity_wide)
	} else {
    	// Измените макет для узкого экрана
    	setContentView(R.layout.activity_narrow)
	}
}

Обработка переключений между дисплеями

Для отслеживания состояния дисплеев и переключения контента между ними используем DisplayManager

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
displayManager.registerDisplayListener(object : DisplayManager.DisplayListener {
	override fun onDisplayAdded(displayId: Int) {
    	// Логика при добавлении дисплея
	}

	override fun onDisplayRemoved(displayId: Int) {
    	// Логика при удалении дисплея
	}

	override fun onDisplayChanged(displayId: Int) {
    	// Логика при изменении состояния дисплея
    	updateContentForDisplay(displayId)
	}
}, null)

// Переключение контента между экранами
private fun updateContentForDisplay(displayId: Int) {
	val display = displayManager.getDisplay(displayId)
	if (display != null && display.isValid) {
    	// Получите информацию о текущем контенте и перенесите его на другой экран
    	transferContentToExternalDisplay()
	}
}

Изменения в поведении приложений

Изменения в API-level 35 повлияют на совместимость приложений по нескольким аспектам.

Ужесточение требований к целевому уровню API 

С 31 августа 2024 года все новые приложения и обновления должны поддерживать Android 14 (API 34) или выше. 

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

Изменения в разрешениях на доступ к мультимедиа 

В Android 15 появились новые разрешения для доступа к медиафайлам. Например, READ_MEDIA_VISUAL_USER_SELECTED. Приложения смогут получить доступ только к тем файлам, которые выбрал пользователь.

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED), REQUEST_CODE)
}

Ограничения на запуск активностей из фоновых процессов

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

Чтобы эти активности запустить, нужно указать разрешение.

 // Пример использования ActivityOptions для разрешения запуска активности из фона
   val options = ActivityOptions.makeBasic().setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
   pendingIntent.send(context, requestCode, options.toBundle())

Необходимость явного указания опции при использовании PendingIntent 

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

 // Создание PendingIntent с опцией для запуска активности из фона
   val pendingIntent = PendingIntent.getActivity(
       context,
       requestCode,
       intent,
       PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
   )

Опция BIND_ALLOW_ACTIVITY_STARTS 

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

// Пример связывания с сервисом с использованием нового флага
   val serviceIntent = Intent(context, MyService::class.java)
   context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE or Context.BIND_ALLOW_ACTIVITY_STARTS)

Запрет на автоматический переход в foreground

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

Ограничение на отправку implicit intents 

Implicit intents теперь могут быть доставлены только экспортируемым компонентам. Если компонент не экспортирован, стоит использовать явный intent.

 // Пример явного intent
   val explicitIntent = Intent(this, MyActivity::class.java)
   startActivity(explicitIntent)

Исключение для mutable pending intents 

Если приложение создает изменяемый PendingIntent с intent, который не указывает компонент или пакет, система выбрасывает исключение.

// Создание безопасного PendingIntent
   val pendingIntent = PendingIntent.getActivity(
       context,
       requestCode,
       explicitIntent,
       PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
   )

Опции для запуска активности из фона 

Чтобы разрешить запуск активности из фона с использованием PendingIntent, нужно указать опцию.

// Установка опции для разрешения запуска активности из фона
   val options = ActivityOptions.makeBasic().setPendingIntentBackgroundActivityStartMode(
       ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
   )
  
   pendingIntent.send(context, requestCode, options.toBundle())

Проверка на наличие разрешений 

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

   if (ContextCompat.checkSelfPermission(context, Manifest.permission.SOME_PERMISSION) == PackageManager.PERMISSION_GRANTED) {
       pendingIntent.send()
   } else {
       // Запрос разрешений
       ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.SOME_PERMISSION), REQUEST_CODE)
   }

Изменения в обработке состояния приложения

Если приложение находится в состоянии остановки (Stopped State), все PendingIntents будут удалены. Приложение получит BOOT_COMPLETED broadcast после выхода из этого состояния.

Запрет на динамическую загрузку кода 

Динамически загружаемый код теперь должен помечаться атрибутом доступа в режиме только для чтения. Это предотвращает выполнение потенциально вредоносного кода.

// Пример использования атрибута доступа только для чтения
   @ReadOnlyAccess
   fun loadDynamicCode() {
       // Логика загрузки кода
   }

Ограничение на обработку zip-архивов

В функциях ZipFile(String) и ZipInputStream.getNextEntry() теперь запрещена обработка zip-архивов, пути в которых начинаются с символа «/» или содержат последовательность «..». Разработчики теперь должны проверять пути перед обработкой файлов.

 val zipFile = ZipFile(zipFilePath)
   if (zipFilePath.startsWith("/") || zipFilePath.contains("..")) {
       throw IllegalArgumentException("Invalid zip file path")
   }

Ужесточение требований к доступу к внутренним компонентам 

Система запрещает отправлять intent-запросы к некоторым внутренним компонентам платформы без указания соответствующих атрибутов доступа. 

Разработчикам придётся указывать атрибуты в манифесте приложения.

 <activity android:name=".MyActivity"
       android:permission="android.permission.READ_ONLY_ACCESS" />

Что в итоге

Android 15 представил ряд полезных улучшений и для пользователей, и для разработчиков. 

Мы, в отделе Android-разработки и тестирования, активно пользуемся 15-й версией. И надо сказать, нам очень нравится. Из самого удобного — Android 15 обзавёлся функциями архивирования и непрерывности для устройств со складным экраном. 

А ещё теперь мы можем более удобно управлять виджетами и мультимедийным возможностями.  Мы получили новые API для более точного контроля параметров HDR, возможность динамической настройки яркости и контрастности в зависимости от сцен. И, конечно, режим веб-камеры и настройку динамической громкости.

Так что пробуйте и делитесь впечатлениями!

Больше полезного про Android — в Telegram-канале Surf Android Team. 

Кейсы, лучшие практики, новости и вакансии в команду Android Surf в одном месте. Присоединяйтесь!

Комментарии (5)


  1. maxsmirnov92
    19.12.2024 09:59

    Спасибо за статью. Пара вопросов по интентам.

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

    В вашем коде вроде нет опций.

    > Если приложение создает изменяемый PendingIntent с intent, который не указывает компонент или пакет, система выбрасывает исключение.

    По отложенным интентам есть такая статья.
    Там написано, что FLAG_MUTABLE был добавлен с Android 12. До Android 12 любые PendingIntents, созданные без флага FLAG_IMMUTABLE, были неявно изменяемыми, если не указан FLAG_IMMUTABLE. Я использую следующую обёртку с флагами при создании PendingIntent:

    fun withMutabilityFlag(flags: Int, mutable: Boolean): Int {
        val mutableFlag = if (mutable) {
            if (isAtLeastS()) PendingIntent.FLAG_MUTABLE else 0
        } else {
            PendingIntent.FLAG_IMMUTABLE
        }
        return flags or mutableFlag
    }
    1. Что было до Android 15, если для изменяемого интента не указывался ComponentName? Понятно, что неявные в таком случае не допускаются, но исключения не было?

    2. "Если вы попытаетесь переопределить значения в PendingIntent, который был создан с FLAG_IMMUTABLE, произойдет тихий сбой, и исходный обернутый Intent будет передан без изменений.". (Т.е. речь не про обновление собственного с флагом FLAG_UPDATE_CURRENT, а про PendingIntent.send, который дополняет исходный обёрнутый интент, который должен быть мутабельным). В Android 15 с этим как? Бросается ли исключение?

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

    А можно плз пример? Какие разрешения могут понадобится непосредственно перед вызовом Activity/Service/Broadcast? Вроде компонент сам должен спрашивать нужное перед конкретным вызовом (или если, это не рантайм, прописывать его для всего аппа или применительно к конкретному компоненту). И как приложение, вызывающее send, должно понять, что спрашивать?


  1. maxsmirnov92
    19.12.2024 09:59

    И по запускам из фона и разрешениям.

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

    Чтобы эти активности запустить, нужно указать разрешение.

    В общем случае, мы не знаем, работает ли наше приложение в background или foreground. Проверяется это кстати так:

    @Throws(RuntimeException::class)
    fun Context.isAppInBackgroundOrThrow(packageName: String): Boolean {
        val am = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
            ?: throw RuntimeException(ActivityManager::class.java.simpleName + " is null")
        if (!isEmpty(packageName)) {
            val runningProcesses = am.runningAppProcesses
            if (runningProcesses != null) {
                for (processInfo in runningProcesses) {
                    if (packageName == processInfo.processName) {
                        return processInfo.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                    }
                }
            }
        }
        throw RuntimeException("Process with name '$packageName' not found")
    }

    Получается, что перед каждым вызовом активности нужно проверять isSelfAppInBackground(), и на основании этого добавлять ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED? Или делать это всегда для перестраховки?

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

    Тут ещё интереснее)..

    1. Узнать я это не могу, т.к. getRunningAppProcesses (и getRunningServices) вернёт только инфу по собственному процессу (в целях очередной безопасности, не помню с какого API). Получается снова указывать всегда?

    2. Связывание может происходить и с собственным сервисом. Будут ли действовать то же правило?

    Система запрещает отправлять intent-запросы к некоторым внутренним компонентам платформы без указания соответствующих атрибутов доступа. 

    Разработчикам придётся указывать атрибуты в манифесте приложения.

    Т.е. мало запроса прописанных пермишнов в корне и запросов в рантайме, надо ещё к каждому компоненту указывать).. Тоже хотелось бы примеры, где такое теперь необходимо.


  1. maxsmirnov92
    19.12.2024 09:59

    Гугл как обычно на своей волне: стремиться сделать разработку рядовых разрабов невыносимее безопаснее и лучше (не забывайте только каждый год поднимать targetSdk, иначе подчистим ваш апп из маркета). А лучшее - враг хорошего, как известно.

    Вот например, в Android 11, startActivityForResult задепрекейтили, заставляя делать данное действие черезregisterForActivityResult . Launcher должен быть зарегистрирован непосредственно при создании Fragment/Activity, но ни в коем случае ни в onCreate или где-то ещё, иначе ругнётся исключением. Подумали ли гугл о том, насколько это вообще удобно и нужно?) Для проверки и запроса рантайм пермишнов я использую свою велосипедную обёртку над EasyPermissions, а та работает на основе requestPermissions с requestCode. Автору библиотеки, которая перестала поддерживаться, теперь нужно переделать всю логику (не забыв поддержать текущую для обратной совместимости для Android < 11).

    Про закручивание гаек в иос-стиле с файловой системой после Android 10 (API 29) с MediaStore вообще молчу (тут можно поностальгировать о том, как удобно было работать с файлами во времена KitKat и ранее). По поводу архивирования данных аппа... А где этот архив хранится и что в нём? Лишние гигабайты из /data и /obb? Гораздо полезнее данные аппа, которые весят в большинстве случаев мало (в приведённом примере с GTA: SA это будет GTASAsf1.b, весящий 198 KB) и которые система пытается скрыть от пользователя (почему кстати десктопные ОС на админских учётках так не делают?), чем пользователи занимались ещё во времена Android 2.2, со временем просто стали забивать и расставаться с данными. Для чего, понятное дело, нужен root (а для его получения и разблокировки загрузчика с каждым следующим API при покупке нового телефона новые танцы с бубном) и SwiftBackup например, который сложит нужные данные. Архив, правда в отличие от TitaniumBackup (который перестал поддерживаться и даже в режиме совместимости при его targetSdk не имеет доступа к /Android/data) будет шифрованный, что минус - восстанавливать обратно только свифтом и просто подсмотреть нельзя. Сделали некоторое время назад флаг в манифесте "allowBackup". Будет ли он работать так, как нужно? Конечно же нет))


  1. maxsmirnov92
    19.12.2024 09:59

    Ограничения на запуск служб при получении BOOT_COMPLETED

    Новые ограничения запрещают запуск служб приоритета (dataSync, camera и других.) при получении широковещательного сообщения BOOT_COMPLETED.

    Вот теперь страдай, если твой сервис с определённым foregroundServiceType попал под ограничения)..

    Изменения в обработке состояния приложения

    Если приложение находится в состоянии остановки (Stopped State), все PendingIntents будут удалены. Приложение получит BOOT_COMPLETED broadcast после выхода из этого состояния.

    После force stop все PendingIntent удалялись и раньше? Вывести его из этого состояния можно только ActivityManager'ом при запуске из лаунчера. Тогда срабатывание BOOT_COMPLETED после этого выглядит максимально странно: зачем он мне, если нужный код и так вызовется не из BroadcastReceiver?.. А там ведь есть ещё LOCKED_BOOT_COMPLETED.


  1. maxsmirnov92
    19.12.2024 09:59

    Мы, в отделе Android-разработки и тестирования, активно пользуемся 15-й версией.

    Вы пользуете реальные устройства или эмуляторы? По последним, если я правильно понимаю, в открытом доступе доступны только x86_64 образы (ARM не даёт развернуть не на ARM-системе, начиная с Android 9) и запустить для AVD от гугла, которые требуют капризный драйвер Hyper-V и чтобы проц поддерживал расширенную виртуализацию с Extended Page Tables (EPT). Проблема в том, что в основной системе с Ryzen у меня уже давно пользуется Genymotion (там последний образ 14-ый и то, только по платной подписке) с VirtualBox, который не терпит никакой Hyper-V и падает в BSOD. А вторая система с процом Xeon E5450, в котором нет EPT - потратил день, но завести никак не смог. Выходит, только AVD или покупать девайс?