Picture in picture w Androidzie

W poprzednim wpisie opisałem, w jaki sposób tworzyć pływające okna w androidzie. Jednak ten sposób ma pewne ograniczenia. Dlatego w Androidzie Oreo wprowadzono Picture in picture. PiP to funkcja znana z YouTube, która minimalizuje twoją zawartość (aktywność, fragment), trzymając ją w rogu podczas wykonywania innych zadań. Możesz minimalizować video i nadal korzystać z aplikacji. Do Androida O można było stosować pływające okna lub korzystać z tego projektu (nie jest już rozwijany). Początkowo PiP wprowadzono w Androidzie 7 dla TV, natomiast dla urządzeń mobilnych dodaną ową funkcję w Androidzie 8.

1. Wsparcie dla PiP w Androidzie.

Aby korzystać z Picture in picture w pliku Manifest.xml musisz dodać wpis (w sekcji dla aktywności):

<activity
            android:name=".MainActivity"
            android:launchMode = "singleTask"
            android:supportsPictureInPicture="true"
            ....
</activity>

supportsPictureInPicture – dodaje wsparcie dla PiP, a launchMode – mówi o tym, aby była tylko jedna instancja aktywności (nie tworzą się duplikaty).
Kolejnym krokiem, który musisz wykonać to w aktywności, która posiada wsparcie Picture in picture wywołać metodę enterPictureInPictureMode(), np.: po naciśnięciu przycisku. Tyle, nic więcej tak naprawdę nie musisz robić, aby zminimalizowało okno aktywności.

2. Parametry dla PiP.

Powyższa instrukcja działa, ale co jeśli chcemy mieć możliwość zmiany rozmiaru okna lub dodania kontrolek? Rozbuduj swój kod o coś takiego:

final ArrayList<RemoteAction> actions = new ArrayList<>();
actions.add(
        new RemoteAction(
                Icon.createWithResource(MainActivity.this, R.drawable.ic_launcher_foreground),
                getString(R.string.info),
                getString(R.string.info_description),
                PendingIntent.getActivity(
                        MainActivity.this,
                        1234,
                        new Intent(
                                Intent.ACTION_VIEW,
                                Uri.parse(getString(R.string.info_uri))),
                        0)));
PictureInPictureParams params = new PictureInPictureParams.Builder()
        .setAspectRatio(new Rational(400,220))
        .setActions(actions)
        .build();
enterPictureInPictureMode(params);
<string name="info_uri" translatable="false">https://myenv.net/</string>

W pierwszej kolejności tworzymy kontrolki (akcje). Jeżeli w Twoim oknie masz zamiar odtwarzać video i masz włączoną MediaSession, to nie musisz tworzyć kontrolek, one automatycznie dodadzą się. W setAspectRatio() ustawiamy wysokość i szerokość naszego okna, a na końcu wywołujemy metodę wraz z parametrami, która zminimalizuje aktywność.

3. Aktywacja przez przycisk „Ekran główny”.

Istnieje również możliwość uruchomienia funkcji Picture in picture po przez naciśnięcie przycisku „Home”. W aktywności musisz nadpisać metodę onUserLeaveHint():

@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onUserLeaveHint () {
       enterPictureInPictureMode(); // or enterPictureInPictureMode(parms);
}

4. Zmiana wyglądu PiP.

Istnieje również możliwość zmiany wyglądu gdy aktywność jest zminimalizowana. Wystarczy nadpisać metodę onPictureInPictureModeChanged():

@Override
public void onPictureInPictureModeChanged (boolean isInPictureInPictureMode, Configuration newConfig) {
    if (isInPictureInPictureMode) {
        btnPip.setVisibility(View.GONE);
        //view.setBackgroundColor(Color.BLUE);
        view.setBackgroundDrawable( ContextCompat.getDrawable(this, R.drawable.gradient) );
        getSupportActionBar().hide();
    } else {
        btnPip.setVisibility(View.VISIBLE);
        view.setBackgroundColor(Color.WHITE);
        getSupportActionBar().show();
    }
}

W tym przypadku gdy tryb PiP jest aktywny, ukrywamy toolbar oraz zmieniamy tło aktywności, a jeżeli aktywność wróci do pierwotnej postaci zmieni na domyślne kolory i przywracamy pasek.

Picture in picture

5. Opuszczenie trybu Picture in Picture.

Aby opuścić tryb PiP i wrócić do pełnoekranowej aktywności, użytkownik musi kliknąć w okno, ale jeśli kliknie w „X” to aplikacja schowa się (nadal będzie działać). Jeżeli chciałbyś, aby po przyciśnięciu przycisku „x” wróciła aktywność wystarczy zrobić to w ten sposób:

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
  super.onPictureInPictureModeChanged(isInPictureInPictureMode);
  if (!isInPictureInPictureMode) {
    getApplication().startActivity(new Intent(this, getClass())
      .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
  }
}

3. Aktualizacja PiP

A co jeśli chciałbyś aktualizować okno PiP? Chcesz odtworzyć inne wideo?  W tym przypadku musisz skorzystać z OnNewIntent(). Metoda ta jest zawsze wywoływana dla działań singleTop/singleTask,. Jeżeli aktywność jest po raz pierwszy tworzona to ta metoda nie zadziała. Ona dopiero zadziała gdy aktywność już jest na stosie zadań.

6. Podsumowanie.

Aplikacja Picture in Picture została wprowadzona do smartfonów w systemie Android O. W tym artykule krótko przedstawiłem czym jest Picture in picture oraz jak go tworzyć i modyfikować w swoim projekcie. A skoro Android O jest na coraz większej gamie urządzeń, warto ten dodatek wykorzystać. Głownie używa się go do oglądania filmów, ale też może posłużyć do nawigacji – wyświetlenie mapy lub prowadzenia rozmów video.

Co dalej?

  • Polub stronę MYENV na Facebooku oraz śledź mnie na Twitterze
  • Zachęcam do komentowania i pisania propozycji tematów, o których chcesz przeczytać
  • Poleć ten wpis za pomocą poniższych przycisków. Będę Ci za to bardzo wdzięczny 🙂
  • Życzę Ci miłego dnia i miłego kodowania 🙂