Memigrasikan Aplikasi Pengirim CCL ke Cast Application Framework (CAF)

Prosedur berikut memungkinkan Anda mengonversi aplikasi pengirim Android dari Cast SDK v2 dengan CCL ke CAF. Semua fungsi CCL telah diterapkan di CAF, jadi setelah bermigrasi, Anda tidak perlu lagi menggunakan CCL.

SDK Pengirim CAF Cast menggunakan CastContext untuk mengelola GoogleAPIClient atas nama Anda. CastContext mengelola siklus proses, error, dan callback yang sangat memudahkan pengembangan aplikasi Cast.

Pengantar

  • Karena desain Pengirim CAF dipengaruhi oleh Library Pendamping Cast, migrasi dari CCL ke Pengirim CAF melibatkan sebagian besar pemetaan class satu per satu dan metodenya.
  • Pengirim CAF masih didistribusikan sebagai bagian dari layanan Google Play menggunakan Android SDK Manager.
  • Paket baru (com.google.android.gms.cast.framework.*) yang telah ditambahkan ke Pengirim CAF, dengan fungsi yang mirip dengan CCL, bertanggung jawab untuk mematuhi checklist Desain Google Cast.
  • Pengirim CAF menyediakan widget yang mematuhi persyaratan UX Cast; widget ini serupa dengan yang disediakan oleh CCL.
  • Pengirim CAF menyediakan callback asinkron yang mirip dengan CCL, untuk melacak status dan mendapatkan data. Tidak seperti CCL, Pengirim CAF tidak menyediakan implementasi tanpa pengoperasian dari berbagai metode antarmuka.

Di bagian berikut, kita akan lebih berfokus pada aplikasi videosentris berdasarkan VideoCastManager CCL, tetapi dalam banyak kasus, konsep yang sama juga berlaku untuk DataCastManager.

Dependensi

CCL dan CAF memiliki dependensi yang sama pada support library AppCompat, support library MediaRouter v7, dan layanan Google Play. Namun, perbedaannya adalah CAF bergantung pada framework Cast baru yang tersedia di layanan Google Play 9.2.0 atau yang lebih baru.

Dalam file build.gradle, hapus dependensi com.google.android.gms:play-services-cast dan com.google.android.libraries.cast.companionlibrary:ccl, lalu tambahkan framework Cast baru:

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'
}

Anda juga dapat menghapus metadata layanan Google Play:

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

Setiap layanan, aktivitas, dan resource yang merupakan bagian dari CAF akan otomatis digabungkan dengan manifes dan resource aplikasi Anda.

Versi Android SDK minimum yang didukung CAF adalah 9 (Gingerbread); versi Android SDK minimum CCL adalah 10.

CCL menyediakan metode praktis, BaseCastManager.checkGooglePlayServices(activity), untuk memverifikasi bahwa versi layanan Google Play yang kompatibel tersedia di perangkat. CAF tidak menyediakannya sebagai bagian dari Cast SDK. Ikuti prosedur Memastikan Perangkat Memiliki APK layanan Google Play untuk memastikan bahwa APK layanan Google Play yang benar diinstal di perangkat pengguna karena update mungkin tidak langsung menjangkau semua pengguna.

Anda tetap harus menggunakan varian Theme.AppCompat untuk tema aplikasi.

Inisialisasi

Untuk CCL, VideoCastManager.initialize() harus dipanggil dalam metode onCreate() instance Aplikasi. Logika ini harus dihapus dari kode class Aplikasi Anda.

Di CAF, langkah inisialisasi eksplisit juga diperlukan untuk framework Cast. Hal ini melibatkan inisialisasi singleton CastContext, menggunakan OptionsProvider yang sesuai untuk menentukan ID aplikasi penerima dan opsi global lainnya. CastContext memiliki peran yang mirip dengan VideoCastManager CCL dengan menyediakan singleton yang berinteraksi dengan klien. OptionsProvider mirip dengan CastConfiguration CCL untuk memungkinkan Anda mengonfigurasi fitur framework Cast.

Jika CastConfiguration.Builder CCL Anda saat ini terlihat seperti ini:

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

Kemudian, dalam CAF, CastOptionsProvider berikut yang menggunakan CastOptions.Builder akan serupa:

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;
    }
}

Lihat aplikasi contoh kami untuk penerapan lengkap OptionsProvider.

Deklarasikan OptionsProvider dalam elemen "application" dari file 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>

Lakukan inisialisasi dengan lambat CastContext di setiap metode onCreate Activity (bukan instance Application):

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

Untuk mengakses singleton CastContext, gunakan:

mCastContext = CastContext.getSharedInstance(this);

Penemuan perangkat

VideoCastManager incrementUiCounter dan decrementUiCounter CCL harus dihapus dari metode onResume dan onPause pada Activities Anda.

Di CAF, proses penemuan dimulai dan dihentikan secara otomatis oleh framework saat aplikasi hadir di latar depan dan berpindah ke latar belakang.

Tombol Cast dan dialog Cast

Seperti pada CCL, komponen ini disediakan oleh support library MediaRouter v7.

Tombol Cast masih diimplementasikan oleh MediaRouteButton dan dapat ditambahkan ke aktivitas Anda (menggunakan ActionBar atau Toolbar), sebagai item menu di menu Anda.

Deklarasi MediaRouteActionProvider dalam xml menu sama dengan dengan 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"/>

Serupa dengan CCL, ganti metode onCreateOptionMenu() untuk setiap Aktivitas, tetapi gunakan CastManagerFactory CAF, bukan CastManager.addMediaRouterButton, untuk menghubungkan MediaRouteButton ke framework 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;
}

Kontrol perangkat

Serupa dengan CCL, di CAF, kontrol perangkat sebagian besar ditangani oleh framework. Aplikasi pengirim tidak perlu menangani (dan tidak boleh mencoba menangani) koneksi ke perangkat dan meluncurkan aplikasi penerima menggunakan GoogleApiClient.

Interaksi antara pengirim dan penerima kini direpresentasikan sebagai "sesi". Class SessionManager menangani siklus proses sesi serta otomatis memulai dan menghentikan sesi sebagai respons terhadap gestur pengguna: sesi dimulai saat pengguna memilih perangkat Cast dalam dialog Cast dan diakhiri saat pengguna mengetuk tombol "Hentikan Transmisi" di dialog Cast atau saat aplikasi pengirim berhenti.

Di CCL, Anda harus memperluas class VideoCastConsumerImpl untuk melacak status sesi transmisi:

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

Di CAF, aplikasi pengirim dapat diberi tahu tentang peristiwa siklus proses sesi dengan mendaftarkan SessionManagerListener pada SessionManager. Callback SessionManagerListener menentukan metode callback untuk semua peristiwa siklus proses sesi.

Metode SessionManagerListener berikut dipetakan dari antarmuka VideoCastConsumer CCL:

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

Deklarasikan class yang mengimplementasikan antarmuka SessionManagerListener dan memindahkan logika VideoCastConsumerImpl ke metode yang cocok:

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) {}
  ...
}

Class CastSession merepresentasikan sesi dengan perangkat Cast. Class ini memiliki metode untuk mengontrol volume perangkat dan status nonaktif, yang dilakukan CCL di BaseCastManager.

Daripada menggunakan VideoCastManager CCL untuk menambahkan konsumen:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Sekarang daftarkan SessionManagerListener Anda:

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

Untuk berhenti memproses peristiwa di CCL:

VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);

Sekarang gunakan SessionManager untuk berhenti memproses peristiwa sesi:

mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
                    CastSession.class);

Untuk memutuskan hubungan secara eksplisit dari perangkat Cast, CCL menggunakan:

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

Untuk CAF, gunakan SessionManager:

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

Untuk menentukan apakah pengirim terhubung ke penerima, CCL menyediakan VideoCastManager.getInstance().isConnected(), tetapi dalam CAF, gunakan SessionManager:

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

Dalam CAF, notifikasi perubahan status volume/bisukan tetap dikirimkan melalui metode callback di Cast.Listener; pemroses ini terdaftar di CastSession. Semua notifikasi status perangkat yang tersisa dikirim melalui callback CastStateListener; pemroses ini terdaftar di CastSession. Pastikan Anda masih membatalkan pendaftaran pemroses saat fragmen, aktivitas, atau aplikasi terkait diarahkan ke latar belakang.

Logika penghubung ulang

CAF mencoba menghubungkan kembali koneksi jaringan yang hilang karena hilangnya sinyal Wi-Fi sementara atau error jaringan lainnya. Langkah ini kini dilakukan pada level sesi. Sesi dapat memasuki status "ditangguhkan" saat koneksi terputus, dan akan bertransisi kembali ke status "terhubung" saat konektivitas dipulihkan. Framework ini akan menghubungkan kembali ke aplikasi penerima dan menghubungkan kembali saluran Cast sebagai bagian dari proses ini.

CAF menyediakan layanan koneksi ulang sendiri, sehingga Anda dapat menghapus CCL ReconnectionService dari manifes:

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

Anda juga tidak memerlukan izin berikut dalam manifes untuk logika koneksi ulang:

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

Layanan koneksi ulang CAF diaktifkan secara default, tetapi dapat dinonaktifkan menggunakan CastOptions.

Selain itu, CAF juga menambahkan dimulainya kembali sesi otomatis yang diaktifkan secara default (dan dapat dinonaktifkan melalui CastOptions). Jika aplikasi pengirim dikirim ke latar belakang atau dihentikan (dengan menggeser atau karena error) saat sesi Cast sedang berlangsung, framework akan mencoba untuk melanjutkan sesi tersebut saat aplikasi pengirim kembali ke latar depan atau diluncurkan kembali; ini ditangani secara otomatis oleh SessionManager, yang akan mengeluarkan callback yang sesuai di instance yang sesuai.

Pendaftaran saluran khusus

CCL menyediakan dua cara untuk membuat saluran pesan khusus ke penerima:

  • CastConfiguration memungkinkan Anda menentukan beberapa namespace dan CCL kemudian akan membuat saluran tersebut untuk Anda.
  • DataCastManager mirip dengan VideoCastManager tetapi berfokus pada kasus penggunaan non-media.

Tidak satu pun dari cara membuat saluran khusus ini yang didukung oleh CAF -- Anda harus mengikuti prosedur Menambahkan Saluran Khusus untuk aplikasi pengirim.

Serupa dengan CCL, untuk aplikasi media, tidak perlu mendaftarkan saluran kontrol media secara eksplisit.

Kontrol media

Di CAF, class RemoteMediaClient setara dengan metode media VideoCastManager. RemoteMediaClient.Listener setara dengan metode VideoCastConsumer. Secara khusus, metode onRemoteMediaPlayerMetadataUpdated dan onRemoteMediaPlayerStatusUpdated dari VideoCastConsumer dipetakan ke metode onMetadataUpdated dan onStatusUpdated dari RemoteMediaClient.Listener masing-masing:

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() {
    }
}

Tidak perlu melakukan inisialisasi atau mendaftarkan objek RemoteMediaClient secara eksplisit; framework akan otomatis membuat instance objek dan mendaftarkan saluran media yang mendasarinya pada waktu mulai sesi jika aplikasi penerima terhubung untuk mendukung namespace media.

RemoteMediaClient dapat diakses sebagai metode getRemoteMediaClient dari objek CastSession.

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

Bukan CCL:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Sekarang gunakan CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

Jumlah pemroses apa pun dapat didaftarkan dengan RemoteMediaClient, yang memungkinkan beberapa komponen pengirim berbagi satu instance RemoteMediaClient yang terkait dengan sesi tersebut.

VideoCastManager CCL menyediakan metode untuk menangani pemutaran media:

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

Ini sekarang diimplementasikan oleh RemoteMediaClient di CAF:

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

Di CAF, semua permintaan media yang dikeluarkan di RemoteMediaClient akan menampilkan RemoteMediaClient.MediaChannelResult melalui callback PendingResult yang dapat digunakan untuk melacak progres dan hasil permintaan.

CCL dan CAF menggunakan class MediaInfo dan MediaMetadata untuk mewakili item media dan memuat media.

Untuk memuat media di CCL, VideoCastManager digunakan:

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

Di CAF, RemoteMediaClient digunakan untuk memuat media:

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

Untuk mendapatkan informasi Media dan status sesi media saat ini di penerima, CCL menggunakan VideoCastManager:

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

Di CAF, gunakan RemoteMediaClient untuk mendapatkan informasi yang sama:

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

Overlay perkenalan

Serupa dengan CCL, CAF menyediakan tampilan kustom IntroductoryOverlay untuk menandai tombol Cast saat pertama kali ditampilkan kepada pengguna.

Daripada menggunakan metode VideoCastConsumer onCastAvailabilityChanged CCL untuk mengetahui kapan harus menampilkan overlay, deklarasikan CastStateListener untuk menentukan kapan tombol Cast terlihat setelah perangkat Cast ditemukan di jaringan lokal oleh 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);
    ...
}

Lacak instance 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;
}

Periksa apakah MediaRouteButton terlihat sehingga overlay perkenalan dapat ditampilkan:

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();
            }
        });
    }
}

Lihat aplikasi contoh kami untuk kode kerja lengkap guna menampilkan overlay perkenalan.

Untuk menyesuaikan gaya overlay pengantar, ikuti prosedur Menyesuaikan Overlay Pengantar.

Pengontrol mini

Sebagai ganti MiniController CAF, gunakan MiniControllerFragment CAF dalam file tata letak aplikasi tempat Anda ingin menampilkan pengontrol mini:

<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 tidak mendukung konfigurasi manual yang didukung oleh MiniController CCL dan juga tidak mendukung fitur Autoplay.

Untuk menyesuaikan gaya dan tombol pengontrol mini, ikuti prosedur Menyesuaikan Pengontrol Mini.

Notifikasi dan layar kunci

Serupa dengan VideoCastNotificationService CCL, CAF menyediakan MediaNotificationService untuk mengelola tampilan notifikasi media saat melakukan transmisi.

Anda harus menghapus hal-hal berikut dari manifes:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL mendukung penyediaan layanan notifikasi kustom dengan CastConfiguration.Builder; yang tidak didukung oleh CAF.

Pertimbangkan inisialisasi CastManager berikut menggunakan 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());

Untuk konfigurasi yang setara di CAF, SDK menyediakan NotificationsOptions.Builder untuk membantu Anda membuat kontrol media untuk notifikasi dan layar kunci ke aplikasi pengirim. Notifikasi dan kontrol layar kunci dapat diaktifkan dengan CastOptions saat menginisialisasi 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();
}

Notifikasi dan kontrol layar kunci selalu diaktifkan di CAF. Selain itu, perhatikan bahwa tombol putar/jeda dan hentikan transmisi disediakan secara default. CAF akan otomatis melacak visibilitas Aktivitas untuk memutuskan kapan harus menampilkan notifikasi media, kecuali untuk Gingerbread. (Untuk Gingerbread, lihat catatan sebelumnya tentang penggunaan registerLifecycleCallbacksBeforeIceCreamSandwich(); panggilan VideoCastManager incrementUiCounter dan decrementUiCounter CCL harus dihapus.)

Untuk menyesuaikan tombol yang ditampilkan di notifikasi, ikuti prosedur Menambahkan Kontrol Media ke Notifikasi dan Layar Kunci.

Pengontrol yang diperluas

CCL menyediakan VideoCastControllerActivity dan VideoCastControllerFragment untuk menampilkan pengontrol yang diperluas saat melakukan transmisi media.

Anda dapat menghapus deklarasi VideoCastControllerActivity dalam manifes.

Di CAF, Anda harus memperluas LuaskanedControllerActivity dan menambahkan tombol Cast.

Untuk menyesuaikan gaya dan tombol yang ditampilkan dalam pengontrol yang diperluas, ikuti prosedur Menyesuaikan Pengontrol yang Diperluas.

Fokus audio

Seperti pada CCL, fokus audio dikelola secara otomatis.

Kontrol volume

Untuk Gingerbread, dispatchKeyEvent diperlukan seperti pada CCL. Di ICS dan di atasnya, untuk kontrol volume CCL dan CAF ditangani secara otomatis.

CAF memungkinkan pengontrolan volume transmisi melalui tombol volume keras pada ponsel di dalam aktivitas aplikasi Anda dan juga menampilkan panel volume visual saat melakukan transmisi pada versi yang didukung. CAF juga menangani perubahan volume melalui volume keras meskipun aplikasi Anda tidak berada di depan, terkunci, atau meskipun layar nonaktif.

Teks tertutup

Di Android KitKat dan di atasnya, teks dapat disesuaikan melalui Setelan Teks, yang ada di bagian Setelan > Aksesibilitas. Namun, versi Android sebelumnya tidak memiliki kemampuan ini. CCL menangani hal ini dengan menyediakan setelan kustom untuk versi sebelumnya dan mendelegasikan ke setelan sistem di KitKat dan versi yang lebih baru.

CAF tidak menyediakan setelan kustom untuk mengubah preferensi teks. Anda harus menghapus referensi CaptionsPreferenceActivity dalam manifes dan XML preferensi Anda.

TracksChooserDialog CCL tidak lagi diperlukan karena perubahan trek teks tertutup ditangani oleh UI pengontrol yang diperluas.

API teks tertutup di CAF mirip dengan v2.

Logging debug

CAF tidak menyediakan setelan logging debug.

Lain-lain

Fitur CCL berikut tidak didukung di CAF:

  • Memperoleh otorisasi sebelum pemutaran dengan memberikan MediaAuthService
  • Pesan UI yang dapat dikonfigurasi

Aplikasi contoh

Lihat perbedaan untuk memigrasikan aplikasi contoh Universal Music Player untuk Android (uamp) kami dari CCL ke CAF.

Kami juga memiliki tutorial codelab dan aplikasi contoh yang menggunakan CAF.