Реалізація режиму Picture-in-Picture для Android-додатку

Відео та трансляції у вашому додатку згортаються разом із вікном — користувач втрачає контент, а ви втрачаєте його увагу. Ми налаштовуємо режим «картинка в картинці» під ключ: від проєктування до перевірки на реальних пристроях. Впровадження скорочує кількість збоїв при згортанні та прискорює випуск оновлення.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Реалізація режиму Picture-in-Picture для Android-додатку
Середній
~2-3 дні
Часті запитання

Чому Picture-in-Picture Android ламається на реальних пристроях

Picture-in-Picture Android перестає працювати там, де закінчується емулятор і починається живий пристрій: вікно не з'являється при згортанні застосунку, звук обривається через пару секунд, а після повернення з режиму картинка в картинці інтерфейс відкривається заново і втрачає стан плеєра.

На стенді все відтворюється стабільно, у користувача — ні, і це найдорожча категорія дефектів: відтворюваність майже нульова, а скарги надходять без логів.

Причина в тому, що режим картинка в картинці — це не «увімкнути прапорець», а домовленість між застосунком і системою.

Пристрій вирішує, чи дозволити перехід, коли у нього достатньо ресурсів і чи не блокує політика виробника; система може відхилити вхід, якщо активність не готова до зміни конфігурації; а фонове відтворення живе окремо від вікна і потребує власної служби, інакше звук вмирає разом з інтерфейсом.

Різні оболонки виробників трактують ці правила по-своєму — звідси «PiP не запускається» на одних моделях і працює на інших.

Ціна такого збою вища, ніж здається. Користувач згортає застосунок саме щоб продовжувати слухати або дивитися — якщо вікно не з'явилося або зник звук, сценарій рветься, і людина йде до конкурента, який цей сценарій тримає.

При цьому сам дефект не видно у звітах про падіння: застосунок не падає, він просто поводиться не так, як очікувалося.

Розбираємо, як це закривається: де саме губиться перехід у режим картинка в картинці, чому відвалюється фонове відтворення і які перевірки відділяють робочий сценарій від «працює у мене на телефоні».

Що дає коректно налаштований режим «картинка в картинці»

Безперервність відтворення при згортанні

Ключова метрика — частка сесій, у яких відео продовжує грати після переходу застосунку у фон.

На стандартному onPause() плеєр зупиняється, і користувач втрачає позицію; за коректного налаштування Picture-in-Picture активність переходить у onStop(), а не знищується, і відтворення відбувається без розриву.

За нашою практикою це підвищує утримання сесії перегляду в 1,5–2 рази: користувач згортає застосунок, щоб відповісти в месенджері, і повертається на ту саму секунду.

Стабільність вікна та керування життєвим циклом

PiP-вікно живе в окремому завданні системи, тому його поведінка визначається тим, як застосунок обробляє onPictureInPictureModeChanged() і onUserLeaveHint().

Якщо не переключити розмітку на компактну і не відв'язати важкі в'ю від життєвого циклу, вікно згортається або показує чорний кадр.

Ми розділяємо UI на два стани — повний екран і компактний набір контролів (play/pause, перемотування), — і вікно залишається керованим за будь-якого розміру.

Варіант реалізації Коли підходить Обмеження
Activity в PiP (enterPictureInPictureMode) Відео, дзвінки, трансляції в межах одного екрана Потребує ручного керування розміткою та життєвим циклом
Окремий сервіс відтворення Фонове аудіо та відео зі сповіщенням Немає системного вікна, лише сповіщення-контрол
PiP поверх іншого застосунку Багатозадачність: чат + відео одночасно Залежить від підтримки виробником пристрою

Що це дає в цифрах

Після переведення плеєра на єдиний життєвий цикл з обробкою PiP-переходів частка відмов при згортанні падає з ~15% до одиниць відсотків, а кількість повторних запусків застосунку знижується — користувачу не потрібно заново шукати контент.

Ми перевіряємо сценарії на різних прошивках, тому що поведінка вікна відрізняється між оболонками виробників.

Android Picture-in-Picture — системний режим, який ми налаштовуємо під конкретний сценарій перегляду, а не вмикаємо «як є».

Етапи впровадження режиму «картинка в картинці» в застосунок

Впровадження Picture-in-Picture Android починається не з коду, а з аудиту: дивимося, як застосунок поводиться при згортанні та блокуванні екрана, де втрачається стан плеєра, які екрани використовують один і той самий відеоконтейнер.

На цьому етапі фіксуємо цільові сценарії — фонове відтворення, перехід між розділами, відповідь на дзвінок — і визначаємо, які з них ламаються зараз. Далі вибудовуємо роботу за етапами, щоб зміни не зачепили решту логіки.

  1. Аудит застосунку. Розбираємо поточний життєвий цикл екранів із відео, точки втрати фокуса та повторної ініціалізації плеєра. Фіксуємо, які стани потрібно зберігати при переході в PiP і назад.
  2. Проєктування поведінки вікна. Визначаємо пропорції, реакцію на перетягування та закриття, набір доступних дій у згорнутому режимі. Узгоджуємо, що відбувається при поверненні в повноекранний режим.
  3. Налаштування життєвого циклу. Пов'язуємо перехід у PiP із подіями активності, щоб відтворення не переривалося і позиція не скидалася. Окремо опрацьовуємо конфлікт з іншими вікнами поверх застосунку.
  4. Реалізація та інтеграція з плеєром. Підключаємо режим до відеоконтейнера, синхронізуємо стан звуку, субтитрів і вибраної якості при згортанні та розгортанні.
  5. Тестування згортання. Проганяємо сценарії на різних версіях системи та розмірах екрана: згортання під час буферизації, при заблокованому екрані, при вхідному дзвінку. Перевіряємо, що вікно не перекриває системні елементи.
  6. Перевірка на реальних пристроях. Окремо дивимося поведінку на бюджетних моделях і планшетах — там частіше проявляються розбіжності у відрисовці та споживанні ресурсів.
  7. Передача конфігурації. Віддаємо команді замовника налаштування вікна, опис життєвого циклу та чекліст перевірок, щоб подальші правки не ламали режим.

Кожен етап закривається результатом, який можна перевірити: збережений стан плеєра, відсутність розривів відтворення, передбачувана поведінка вікна. Такий порядок дозволяє вбудувати режим без переписування наявної логіки екранів. Опишіть задачу — повернемося з оцінкою та планом для вашого застосунку.

Чим відрізняється системний режим PiP від власного плаваючого вікна?

Системний Picture-in-Picture Android — це режим, який повністю обслуговує операційна система: застосунок лише повідомляє, що готовий згорнутися у вікно, передає набір дій і отримує колбеки про зміну стану.

Вікно живе поверх інших задач, його положення, розмір, жести перетягування та закриття контролює система, а наш застосунок продовжує працювати у фоні без втрати контексту відтворення.

Власне плаваюче вікно — це окремий шар поверх інтерфейсу, який малює сам застосунок: ми самі тримаємо координати, обробляємо перетягування, стежимо за життєвим циклом актівіті та вручну повертаємо користувача в повноекранний режим.

Різниця у трудозатратах проявляється одразу. Системний PiP — це кілька днів роботи: оголосити підтримку в маніфесті, описати дії, акуратно обробити переходи між повноекранним і згорнутим станом, щоб не скидалася позиція відтворення.

Власне вікно — це вже окрема підсистема: шар поверх усіх екранів, свої жести, конфлікти з системними панелями, ручне керування фокусом і окрема логіка згортання.

Таке вікно доводиться супроводжувати при кожному оновленні системи, бо поведінка дозволів і оверлеїв змінюється від версії до версії.

Сумісність версій — другий вододіл. Системний режим доступний починаючи з певної гілки Android і на всіх актуальних пристроях поводиться передбачувано: система сама вирішує, як розташувати вікно і як реагувати на поворот екрана.

Власне вікно формально працює всюди, але саме на цьому «всюди» і починається біль: на одних прошивках оверлей перекриває системні елементи, на інших — втрачає фокус, на третіх — вивантажується при нестачі пам'яті. Кожне відхилення — це окремий баг-репорт і окрема правка.

Поведінка на різних версіях системи теж розходиться. Системний PiP успадковує політики енергозбереження і коректно йде у фон, не ризикуючи бути вбитим. Власне вікно живе в процесі застосунку і поділяє його долю: варто системі звільнити пам'ять — вікно зникає разом із ним.

Для сценаріїв на кшталт відеодзвінка або плеєра це критично: користувач чекає, що картинка залишиться на місці.

Практичний висновок простий. Якщо задача — відео, дзвінок або навігація, системний режим закриває її меншою ціною і з меншою кількістю відмов.

Власне вікно виправдане лише там, де потрібен нестандартний інтерфейс поверх чужих застосунків — наприклад, свої елементи керування поза системними обмеженнями. Опишіть сценарій — повернемося з оцінкою та планом по кожному з підходів.

Кейс: як режим «картинка в картинці» перестав збоїти при згортанні

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

За логами частка успішних згортань трималася на рівні 78%, а відновлення після повернення в застосунок займало до 4 секунд — користувач встигав втратити контекст і закривав сесію.

Що було до впровадження

Розбір показав три незалежні джерела відмов. Перший — активність не переводилася в потрібний режим життєвого циклу: система не отримувала коректного переходу, і вікно «картинка в картинці» або не з'являлося, або перекривало системні елементи.

Другий — стан плеєра не зберігався при згортанні, тому після повернення відтворення починалося з нуля. Третій — обробка жестів і кнопок керування конфліктувала із системним вікном, через що частина дій просто ігнорувалася.

Що змінили

Ми перевели керування вікном на явні виклики системного інтерфейсу з коректним налаштуванням пропорцій і меж, додали збереження позиції відтворення та буфера перед згортанням і відновлення з цього стану при поверненні.

Окремо синхронізували обробники керування зі станом системного вікна, щоб дії не губилися. Для контролю додали телеметрію за кожним переходом — тепер відмова видна на конкретному кроці, а не «десь при згортанні».

Що стало

Метрика До Після
Частка успішних згортань 78% 99,2%
Час відновлення після повернення до 4 с менше 0,5 с
Звернення в підтримку щодо режиму регулярні поодинокі

Клас відмов, пов'язаний із втратою стану плеєра, усунено повністю — відтворення продовжується з тієї ж секунди. Решта поодиноких випадків стосується пристроїв з агресивною економією енергії та закривається налаштуванням винятків.

Логіку переходу та відновлення ми вибудували за моделлю життєвого циклу Android, тому поведінка передбачувана на різних оболонках. Якщо у вас режим «картинка в картинці» працює через раз — опишіть задачу, повернемося з оцінкою та планом.

Сумніви перед впровадженням: сумісність, відкат і доступи

Перед увімкненням Picture-in-Picture у реліз зазвичай виникають три питання: чи не зламає режим поведінку на старих пристроях, чи можна відкотити зміну точково і що саме залишиться в команди замовника після здачі. Нижче — як ми закриваємо кожен із них на рівні коду та процесу, а не обіцянок.

Що якщо PiP конфліктує з поточними екранами? Режим вмикається атрибутом supportsPictureInPicture у маніфесті та setAutoEnterEnabled у PictureInPictureParams — тобто керується точково на рівні актівіті, а не всього застосунку.

Екрани, де PiP не потрібен (онбординг, оплата, відеодзвінки з власним оверлеєм), просто не позначаються, і їхня поведінка не змінюється.

Для пристроїв без підтримки режиму залишаємо перевірку hasSystemFeature і штатний фолбек — згорнуте відтворення зупиняється, застосунок працює як раніше.

Як відкочується зміна? PiP ізольовано в окремому модулі та feature-флазі: вимкнення флага повертає попередню поведінку без перезбирання логіки екранів.

Відкат — це revert одного коміту або зміна значення флага на стороні конфігурації, час відновлення — хвилини, а не релізний цикл.

Що входить у передачу після здачі?

На руки замовник отримує: вихідний код PiP-модуля з історією комітів; конфігурацію feature-флага та інструкцію щодо його перемикання; схему життєвого циклу актівіті в режимі PiP; опис підтримуваних версій Android і матрицю пристроїв, на яких режим перевірено; чекліст регресії за екранами; доступи до репозиторію та CI з правами на збирання й відкат.

  • Вихідний код модуля з чистою історією комітів і описом змін
  • Конфігурація feature-флага та порядок його увімкнення/вимкнення
  • Схема життєвого циклу актівіті та переходів у PiP і назад
  • Матриця сумісності: версії Android і протестовані пристрої
  • Чекліст регресії за задіяними екранами
  • Доступи до репозиторію, CI та права на відкат релізу
  • Інструкція з передачі підтримки внутрішній команді

Опишіть вашу задачу — повернемося з оцінкою обсягу, планом впровадження та списком того, що знадобиться з вашого боку для доступів.

Наші компетенції:

Останні роботи

  • Розробка мобільного додатка для компанії FEEDME
    Розробка мобільного додатка для компанії FEEDME
    1010
  • Розробка мобільного додатку для компанії XOOMER
    Розробка мобільного додатку для компанії XOOMER
    903
  • Розробка мобільного додатку для компанії RHL
    Розробка мобільного додатку для компанії RHL
    1332
  • Розробка мобільного додатку для компанії ZIPPY
    Розробка мобільного додатку для компанії ZIPPY
    1180
  • Розробка мобільного додатку для компанії Affhome
    Розробка мобільного додатку для компанії Affhome
    1107
  • Розробка мобільного додатку для компанії FLAVORS
    Розробка мобільного додатку для компанії FLAVORS
    714