Migracja aplikacji CCL Sender do środowiska Cast Application Framework (CAF)

Wykonując poniższą procedurę, możesz przekonwertować aplikację wysyłającą na Androida z Przesyłanie pakietu SDK w wersji 2 z CCL do CAF. Wszystkie funkcje CCL zostały wdrożony w CAF, więc po migracji nie będzie już trzeba korzystać z CCL.

Pakiet SDK Cast CAF Sender wykorzystuje CastContext do zarządzania GoogleAPIClient w Twoim imieniu. CastContext zarządza cyklami życia, błędami i wywołaniami zwrotnymi, co znacznie ułatwia tworzenie aplikacji Cast.

Wprowadzenie

  • Ponieważ na projekt nadawcy CAF wpłynęła biblioteka towarzysząca Cast, migracja z CCL do nadawcy CAF obejmuje głównie mapowania 1:1 i ich metodach.
  • Nadawca CAF jest nadal rozpowszechniany w ramach Usług Google Play za pomocą Menedżera Android SDK.
  • Nowe pakiety (com.google.android.gms.cast.framework.*), które zostały do aplikacji CAF Sender – działa podobnie jak w przypadku listy CCL z odpowiedzialnością za przestrzeganie Lista kontrolna do projektowania w Google Cast.
  • Nadawca CAF zapewnia widżety zgodne z wymaganiami dotyczącymi UX Cast. są podobne do widżetów dostępnych w CCL.
  • CAF Sender udostępnia asynchroniczne wywołania zwrotne podobne do CCL w celu śledzenia i pozyskiwanie danych. W przeciwieństwie do listy CCL nadawca CAF nie zapewnia żadnego działania no-op przy użyciu różnych metod interfejsu.

W kolejnych sekcjach skupimy się głównie na kwestiach wideo oparte na VideoCastManager, ale w wielu przypadkach koncepcje te mają też zastosowanie do usługi DataCastManager.

Zależności

CCL i CAF mają takie same zależności od biblioteki pomocy AppCompat, Obsługa biblioteki MediaRouter w wersji 7 i Usług Google Play. Jednak różnica jest to, że CAF zależy od nowej platformy Cast dostępnej w Google Play. usługi w wersji 9.2.0 lub nowszej.

W pliku build.gradle usuń zależności com.google.android.gms:play-services-cast i com.google.android.libraries.cast.companionlibrary:ccl, i dodaj nową platformę Cast:

dependencies {
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:mediarouter-v7:23.4.0'
    compile 'com.google.android.gms:play-services-cast-framework:9.4.0'
}

Możesz też usunąć metadane usługi Google Play:

<meta‐data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>

Wszystkie usługi, działania i zasoby, które wchodzą w skład CAF, są automatycznie z plikiem manifestu i zasobami aplikacji.

Minimalna wersja pakietu Android SDK obsługiwana przez CAF to 9 (Gingerbread); Minimalna wersja pakietu SDK na Androida dla listy CCL to 10.

CCL to wygodna metoda, BaseCastManager.checkGooglePlayServices(activity), by sprawdzić, czy zgodny plik wersja usług Google Play jest dostępna na urządzeniu. CAF nie możesz go udostępniać w ramach pakietu Cast SDK. Wykonaj procedurę Sprawdzanie, czy na urządzeniach jest zainstalowany plik APK Usług Google Play aby upewnić się, że w pliku APK użytkownika jest zainstalowany prawidłowy plik APK Usług Google Play urządzenia, bo aktualizacje mogą nie dotrzeć od razu do wszystkich użytkowników.

Nadal musisz używać wariantu motywu Theme.AppCompat na potrzeby funkcji motyw.

Zdarzenie inicjujące

W przypadku listy CCL wymagane było wywołanie funkcji VideoCastManager.initialize() w funkcji Metoda onCreate() instancji aplikacji. Ta logika powinna być został usunięty z kodu klasy aplikacji.

W CAF wymagany jest też jawny krok inicjowania dla przesyłania platformy. Wymaga to zainicjowania singletonu CastContext za pomocą odpowiednie OptionsProvider, aby określić identyfikator aplikacji odbiorcy i wszelkie inne opcje globalne. CastContext pełni podobną rolę do listy CCL, VideoCastManager, oferując pojedynczy produkt, z którym klienci wchodzą w interakcje. Aplikacja OptionsProvider jest podobna do CastConfiguration na liście CCL, aby umożliwić Ci aby skonfigurować funkcje platformy Cast.

Jeśli Twoja bieżąca lista kontroli dostępu (CastConfiguration.Builder) wygląda tak:

VideoCastManager.initialize(
   getApplicationContext(),
   new CastConfiguration.Builder(context.getString(R.string.app_id))
       .enableWifiReconnection()
       .enableAutoReconnect()
       .build());

Następnie w CAF następujący CastOptionsProvider, korzystając z CastOptions.Builder byłby podobny:

public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(
            Context context) {
        return null;
    }
}

Przyjrzyj się naszej przykładowej aplikacji. .

Zadeklaruj OptionProvider w elemencie „application” elementu Plik AndroidManifest.xml:

<application>
...
    <meta-data
        android:name=
          "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.google.sample.cast.refplayer.CastOptionsProvider"    
    />
</application>

Leniwie zainicjuj CastContext w metodzie onCreate każdego elementu Activity (a nie wystąpienie Application):

private CastContext mCastContext;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.video_browser);
    setupActionBar();

    mCastContext = CastContext.getSharedInstance(this);
}

Aby uzyskać dostęp do usługi singleton CastContext, użyj polecenia:

mCastContext = CastContext.getSharedInstance(this);

Wykrywanie urządzeń

Uprawnienia VideoCastManager (incrementUiCounter i decrementUiCounter) listy CCL powinny zostanie usunięty z metod onResume i onPause na Activities.

W CAF proces wykrywania jest uruchamiany i zatrzymywany automatycznie przez gdy aplikacja działa na pierwszym planie i działa w tle, .

Przycisk przesyłania i okno przesyłania

Podobnie jak w przypadku listy CCL, te komponenty są dostarczane przez obsługę MediaRouter v7 bibliotece.

Przycisk Cast jest nadal zaimplementowany przez MediaRouteButton i można go dodać do Twojej aktywności (za pomocą ActionBar lub Toolbar), jako pozycja menu w menu.

Deklaracja elementu MediaRouteActionProvider w pliku XML menu jest taka sama jak z listą CCL:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

Podobnie jak w przypadku listy CCL, zastąp metodę onCreateOptionMenu() dla każdej aktywności, ale zamiast CastManager.addMediaRouterButton, użyj funkcji CastButtonFactory w CAF by połączyć MediaRouteButton z platformą Cast:

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
                                                menu,
                                                R.id.media_route_menu_item);
    return true;
}

Sterowanie urządzeniem

Podobnie jak w przypadku CCL, w CAF sterowanie urządzeniem jest obsługiwane w dużej mierze przez platformę. Aplikacja nadawcy nie musi obsługiwać (i nie powinna próbować tego robić) nawiązywanie połączenia z urządzeniem i uruchamianie aplikacji odbiornika za pomocą GoogleApiClient

Interakcja między nadawcą a odbiorcą jest teraz prezentowana jako „sesja”. Klasa SessionManager obsługuje cykl życia sesji i automatycznie uruchamia się i zatrzymuje sesję w odpowiedzi na gesty użytkownika: sesja rozpoczyna się, gdy użytkownik wybiera urządzenie przesyłające w oknie przesyłania i kończy, gdy użytkownik go kliknie komunikat „Zatrzymaj przesyłanie” w oknie przesyłania lub gdy aplikacja nadawcy kończy się.

W CCL musisz rozszerzyć klasę VideoCastConsumerImpl, aby śledzić przesyłanie. stan sesji:

private final VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {
  public void onApplicationConnected(ApplicationMetadata appMetadata, 
                                     String sessionId,
                                     boolean wasLaunched) {}
  public void onDisconnectionReason(int reason) {}
  public void onDisconnected() {}
}

W CAF aplikacja nadawcy może być powiadamiana o zdarzeniach cyklu życia sesji przez rejestrując SessionManagerListener w SessionManager. Wywołania zwrotne SessionManagerListener definiują metody wywołań zwrotnych dla wszystkich sesji zdarzenia cyklu życia.

Poniższe metody typu SessionManagerListener są mapowane z listy CCL Interfejs VideoCastConsumer:

  • VideoCastConsumer.onApplicationConnected -> SessionManagerListener.onSessionStarted
  • VideoCastConsumer.onDisconnected -> SessionManagerListener.onSessionEnded

Zadeklaruj klasę, która implementuje interfejs SessionManagerListener, i przenieś logikę VideoCastConsumerImpl do metod dopasowywania:

private class CastSessionManagerListener implements SessionManagerListener<CastSession> {
  public void onSessionEnded(CastSession session, int error) {}
  public void onSessionStarted(CastSession session, String sessionId) {}
  public void onSessionEnding(CastSession session) {}
  ...
}

Klasa CastSession reprezentuje sesję z urządzeniem przesyłającym. Zajęcia mają do sterowania głośnością urządzenia i stanów wyciszenia, które są dostępne w aplikacji CCL w BaseCastManager

Zamiast używać listy CCL VideoCastManager do dodawania konsumenta:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Teraz zarejestruj urządzenie SessionManagerListener:

mCastSessionManager = 
    CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
                  CastSession.class);

Aby przestać nasłuchiwać zdarzeń w CCL:

VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);

Teraz użyj narzędzia SessionManager, aby przestać nasłuchiwać zdarzeń w sesji:

mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
                    CastSession.class);

Do jednoznacznego odłączenia urządzenia przesyłającego użyto listy CCL:

VideoCastManager.disconnectDevice(boolean stopAppOnExit, 
            boolean clearPersistedConnectionData,
            boolean setDefaultRoute)

W przypadku CAF użyj SessionManager:

CastContext.getSharedInstance(this).getSessionManager()
                                   .endCurrentSession(true);

Aby określić, czy nadawca jest połączony z odbiorcą, CCL udostępnia VideoCastManager.getInstance().isConnected(), ale w CAF użyj makra SessionManager:

public boolean isConnected() {
    CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                  .getSessionManager()
                                  .getCurrentCastSession();
    return (castSession != null && castSession.isConnected());
}

W CAF powiadomienia o zmianie głośności/stanu wyciszenia są nadal dostarczane przez wywołanie zwrotne Cast.Listener; ci słuchacze są zarejestrowani w CastSession Wszystkie pozostałe powiadomienia o stanie urządzenia są dostarczane przez CastStateListener wywołań zwrotnych; ci słuchacze są zarejestrowani w CastSession Pamiętaj, aby wyrejestrować detektory, gdy powiązane fragmenty, działania lub aplikacje mogą pojawiać się w tle.

Logika ponownego połączenia

CAF próbuje przywrócić połączenia sieciowe, które zostały utracone z powodu do tymczasowej utraty sygnału Wi-Fi lub innych błędów sieci. Obecnie odbywa się to w poziom sesji; sesja może zostać zawieszona gdy połączenie jest i przejdzie z powrotem do stanu „połączonego” stan, gdy połączenie to przywrócono. Platforma zapewnia ponowne połączenie z aplikacją odbierającą i ponownie podłącz wszystkie kanały przesyłające.

CAF udostępnia własną usługę ponownego połączenia, więc możesz usunąć lista CCL ReconnectionService z pliku manifestu:

<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>

W pliku manifestu nie potrzebujesz też tych uprawnień zasady ponownego połączenia:

<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Usługa ponownego połączenia CAF jest domyślnie włączona, ale można ją wyłączyć za pomocą CastOptions

Oprócz tego funkcja CAF dodaje też automatyczne wznawianie sesji, które jest włączone przez domyślnie (i można go dezaktywować za pomocą funkcji CastOptions). Jeśli aplikacja nadawcy to są wysyłane w tle lub zostały przerwane (przez przesunięcie palcem lub w wyniku wypadku) w trakcie sesji przesyłania platforma spróbuje ją wznowić. sesja, gdy aplikacja nadawcy powraca na pierwszy plan lub zostaje ponownie uruchomiona; jest on obsługiwany automatycznie przez usługę SessionManager, która generuje odpowiednie wywołania zwrotne we wszystkich zarejestrowanych instancjach SessionManagerListener.

Rejestracja kanału niestandardowego

Lista CCL udostępnia 2 sposoby tworzenia niestandardowego kanału wiadomości dla odbiorcy:

  • CastConfiguration umożliwia określenie wielu przestrzeni nazw, a lista CCL będzie a potem utwórz dla siebie kanał.
  • Program DataCastManager jest podobny do platformy VideoCastManager, ale koncentruje się na formatach innych niż media i przypadków użycia.

Żaden z tych sposobów tworzenia kanału niestandardowego nie jest obsługiwany przez CAF – muszą zamiast tego wykonać procedurę Dodawanie kanału niestandardowego dla aplikacji nadawcy.

Podobnie jak w przypadku listy CCL, w przypadku aplikacji multimedialnych nie trzeba zarejestrować kanał sterowania multimediami.

Sterowanie multimediami

W CAF klasa RemoteMediaClient jest odpowiednikiem funkcji VideoCastManager metod komunikacji. RemoteMediaClient.Listener jest odpowiednikiem funkcji VideoCastConsumer metody. W szczególności onRemoteMediaPlayerMetadataUpdated i onRemoteMediaPlayerStatusUpdated metody VideoCastConsumer są mapowane na onMetadataUpdated i onStatusUpdated metody RemoteMediaClient.Listener odpowiednio:

private class CastMediaClientListener implements RemoteMediaClient.Listener {

    @Override
    public void onMetadataUpdated() {
        setMetadataFromRemote();
    }

    @Override
    public void onStatusUpdated() {
        updatePlaybackState();
    }

    @Override
    public void onSendingRemoteMediaRequest() {
    }

    @Override
    public void onQueueStatusUpdated() {
    }

    @Override
    public void onPreloadStatusUpdated() {
    }
}

Nie jest konieczne bezpośrednie inicjowanie ani rejestrowanie obiektu RemoteMediaClient obiektu; platforma automatycznie utworzy instancję obiektu i zarejestruje bazowego kanału mediów w momencie rozpoczęcia sesji, jeśli aplikacja odbierająca Połączenie z usługą obsługuje przestrzeń nazw multimediów.

Do obiektu RemoteMediaClient można uzyskać dostęp jako metodę getRemoteMediaClient funkcji obiekt CastSession.

CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                     .getSessionManager()
                                     .getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();

Zamiast list CCL:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Teraz użyj CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

W RemoteMediaClient można zarejestrować dowolną liczbę detektorów, co umożliwia wielu komponentom nadawcy współdzielenie pojedynczej instancji Identyfikator RemoteMediaClient powiązany z sesją.

VideoCastManager w CCL udostępnia metody obsługi odtwarzania multimediów:

VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
    manager.pause();
    mCurrentPosition = (int) manager.getCurrentMediaPosition();
}

Są one teraz wdrażane przez RemoteMediaClient w CAF:

if (mRemoteMediaClient.hasMediaSession()) {
    mRemoteMediaClient.pause();
    mCurrentPosition = 
        (int)mRemoteMediaClient.getApproximateStreamPosition();
}

W CAF wszystkie żądania mediów wysłane w RemoteMediaClient zwracają błąd RemoteMediaClient.MediaChannelResult, przez wywołanie zwrotne typu PendingResult które mogą służyć do śledzenia postępów i ostatecznych wyników rozpatrzenia prośby.

Zarówno CCL, jak i CAF używają klas MediaInfo i MediaMetadata do reprezentowania elementów multimedialnych i wczytywać multimedia.

Do wczytywania multimediów w aplikacji CCL używany jest VideoCastManager:

VideoCastManager.getInstance().loadMedia(media, autoPlay, mCurrentPosition, customData);

W CAF do wczytywania multimediów używany jest obiekt RemoteMediaClient:

mRemoteMediaClient.load(media, autoPlay, mCurrentPosition, customData);

Aby uzyskać informacje o Media i stan bieżącej sesji multimediów na odbiornika, CCL używa klucza VideoCastManager:

MediaInfo mediaInfo = VideoCastManager.getInstance()
                                      .getRemoteMediaInformation();
int status = VideoCastManager.getInstance().getPlaybackStatus();
int idleReason = VideoCastManager.getInstance().getIdleReason();

W CAF użyj parametru RemoteMediaClient, aby uzyskać te same informacje:

MediaInfo mediaInfo = mRemoteMediaClient.getMediaInfo();
int status = mRemoteMediaClient.getPlayerState();
int idleReason = mRemoteMediaClient.getIdleReason();

Nakładka wprowadzająca

Podobnie jak w przypadku listy CCL, CAF udostępnia widok niestandardowy IntroductoryOverlay do wyróżnienia przycisk Cast, gdy wyświetla się on po raz pierwszy.

Zamiast używać metody VideoCastConsumer onCastAvailabilityChanged listy CCL aby wiedzieć, kiedy wyświetlić nakładkę, zadeklaruj CastStateListener, aby określić gdy przycisk Cast staje się widoczny po wykryciu urządzeń przesyłających sieć lokalna przez MediaRouter:

private IntroductoryOverlay mIntroductoryOverlay;
private MenuItem mMediaRouteMenuItem;

protected void onCreate(Bundle savedInstanceState) {
    ...
    mCastStateListener = new CastStateListener() {
        @Override
        public void onCastStateChanged(int newState) {
            if (newState != CastState.NO_DEVICES_AVAILABLE) {
                showIntroductoryOverlay();
            }
        }
    };
    mCastContext = CastContext.getSharedInstance(this);
    mCastContext.registerLifecycleCallbacksBeforeIceCreamSandwich(this, 
        savedInstanceState);
}

protected void onResume() {
    mCastContext.addCastStateListener(mCastStateListener);
    ...
}

protected void onPause() {
    mCastContext.removeCastStateListener(mCastStateListener);
    ...
}

Śledź instancję MediaRouteMenuItem:

public boolean onCreateOptionsMenu(Menu menu) {
   super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    mMediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(
            getApplicationContext(), menu,
            R.id.media_route_menu_item);
    showIntroductoryOverlay();
    return true;
}

Sprawdź, czy ikona MediaRouteButton jest widoczna, aby wyświetlić nakładkę wprowadzającą mogą się wyświetlać:

private void showIntroductoryOverlay() {
    if (mIntroductoryOverlay != null) {
        mIntroductoryOverlay.remove();
    }
    if ((mMediaRouteMenuItem != null) && mMediaRouteMenuItem.isVisible()) {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                mIntroductoryOverlay = new IntroductoryOverlay.Builder(
                        VideoBrowserActivity.this, mMediaRouteMenuItem)
                        .setTitleText(getString(R.string.introducing_cast))
                        .setOverlayColor(R.color.primary)
                        .setSingleTime()
                        .setOnOverlayDismissedListener(
                                new IntroductoryOverlay
                                    .OnOverlayDismissedListener() {
                                        @Override
                                        public void onOverlayDismissed() {
                                            mIntroductoryOverlay = null;
                                        }
                                })
                        .build();
                mIntroductoryOverlay.show();
            }
        });
    }
}

Zapoznaj się z naszą przykładowa aplikacja dla pełnego kodu umożliwiającego wyświetlenie nakładki wprowadzającej.

Aby dostosować styl nakładki wprowadzającej, postępuj zgodnie z procedurą Dostosuj nakładkę wprowadzającą.

Minikontroler

Zamiast MiniController listy CCL użyj identyfikatora MiniControllerFragment CAF w plik układu aplikacji z działaniami, w których chcesz wyświetlać mini kontroler:

<fragment
        android:id="@+id/cast_mini_controller"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:castShowImageThumbnail="true"
        android:visibility="gone"
        class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment" />

CAF nie obsługuje konfiguracji ręcznej obsługiwanej przez interfejs MiniController CCL. Nie obsługuje też funkcji Autoplay.

Aby dostosować styl i przyciski minikontrolera, postępuj zgodnie z instrukcjami procedura Dostosuj minikontroler.

Powiadomienia i ekran blokady

Podobnie jak VideoCastNotificationService na liście CCL, CAF zapewnia MediaNotificationService do zarządzania wyświetlaniem powiadomień o multimediach podczas przesyłania.

Musisz usunąć z pliku manifestu te elementy:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL umożliwia udostępnianie niestandardowych usług powiadomień z CastConfiguration.Builder; który nie jest obsługiwany przez CAF.

Rozważ takie zainicjowanie CastManager przy użyciu listy kontroli dostępu (CCL):

VideoCastManager.initialize(
   getApplicationContext(),
   new CastConfiguration.Builder(
           context.getString(R.string.app_id))
       .addNotificationAction(
           CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE,true)
       .addNotificationAction(
           CastConfiguration.NOTIFICATION_ACTION_DISCONNECT,true)
       .build());

W przypadku równoważnej konfiguracji w CAF pakiet SDK udostępnia NotificationsOptions.Builder, która pomoże Ci tworzyć elementy sterujące multimediami powiadomienia i ekranu blokady w aplikacji nadawcy. Powiadomienie i blokada elementy sterujące ekranem można włączyć za pomocą elementu CastOptions podczas inicjowania CastContext

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = 
        new NotificationOptions.Builder()
            .setActions(Arrays.asList(
                MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
                MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{0, 1})
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
             .setNotificationOptions(notificationOptions)
             .build();
    return new CastOptions.Builder()
             .setReceiverApplicationId(context.getString(R.string.app_id))
             .setCastMediaOptions(mediaOptions)
             .build();
}

Powiadomienia i ustawienia ekranu blokady są zawsze włączone w CAF. Pamiętaj też, że przyciski odtwarzania/wstrzymywania i zatrzymywania przesyłania są domyślnie dostępne. CAF automatycznie śledzi widoczność aktywności, aby podjąć decyzję Kiedy ma się wyświetlić powiadomienie o multimediach (oprócz Gingerbread). W przypadku wersji Gingerbread przeczytaj wcześniejszą uwagę za pomocą funkcji registerLifecycleCallbacksBeforeIceCreamSandwich(); Listy CCL VideoCastManager połączenia typu incrementUiCounter i decrementUiCounter powinno zostać usunięte).

Aby dostosować przyciski wyświetlane w powiadomieniach, postępuj zgodnie z procedura Dodawanie opcji sterowania multimediami do ekranu powiadomień i ekranu blokady

Rozwinięty kontroler

CCL udostępnia VideoCastControllerActivity i VideoCastControllerFragment aby wyświetlić rozszerzony kontroler podczas przesyłania multimediów.

Możesz usunąć deklarację VideoCastControllerActivity z pliku manifestu.

W CAF musisz: Rozszerz zakres ExtendedControllerActivity i dodaj przycisk Cast.

Aby dostosować style i przyciski wyświetlane w rozwiniętym menu dla kontrolera, postępuj zgodnie z procedurą Dostosuj rozszerzony kontroler.

Aktywność audio

Podobnie jak w przypadku listy CCL, sterowanie dźwiękiem jest zarządzane automatycznie.

Sterowanie głośnością

W przypadku wersji Gingerbread, tak jak w przypadku CCL, wymagana jest właściwość dispatchKeyEvent. W ICS i nowszych zarówno w przypadku sterowania głośnością z listy CCL, jak i CAF, odbywa się automatycznie.

CAF umożliwia sterowanie głośnością przesyłania za pomocą twardego przycisku głośności na telefonu w aplikacjach, a także wyświetla pasek głośności, gdy jest obsługiwane. CAF obsługuje też zmianę głośności nawet wtedy, gdy aplikacja nie znajduje się z przodu, jest zablokowana lub ekran wyłączone.

Napisy

W Androidzie KitKat i nowszych napisy można dostosować za pomocą napisów Ustawienia w sekcji Ustawienia > Ułatwienia dostępu. Wcześniejsze wersje Androida nie mają takiej możliwości. CCL robi to, stosując ustawienia starszych wersji i przekazywanie ustawień systemu w systemie KitKat i innych.

CAF nie udostępnia niestandardowych ustawień umożliwiających zmianę preferencji napisów. Ty powinien usunąć odwołania do CaptionsPreferenceActivity z pliku manifestu i pliku XML ustawień.

Pole TracksChooserDialog listy kontroli dostępu nie jest już potrzebne ze względu na zmianę zamknięcia ścieżki z napisami są obsługiwane przez rozwinięty interfejs kontrolera.

Interfejs API do tworzenia napisów (closed captioning API) w CAF jest podobny do wersji 2.

Logowanie debugowania

CAF nie udostępnia ustawień logowania debugowania.

Inne

Te funkcje CCL nie są obsługiwane w CAF:

  • Uzyskanie autoryzacji przed odtworzeniem za pomocą MediaAuthService
  • Konfigurowalne komunikaty w interfejsie

Przykładowe aplikacje

Zapoznaj się z różnicami związanymi z migracją przykładowej aplikacji Universal Music Player na Androida (uamp) z CCL do CAF.

Dostępne są też samouczki z programowania i przykładowe aplikacje korzystające z CAF.