Memigrasikan Aplikasi Pengirim CCL ke Framework Aplikasi Cast (CAF)

Prosedur berikut memungkinkan Anda untuk mengonversi aplikasi pengirim Android Anda dari Transmisikan SDK v2 dengan CCL ke CAF. Semua fungsi CCL telah diimplementasikan di CAF, sehingga 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 untuk Anda, yang sangat menyederhanakan pengembangan aplikasi Cast.

Pengantar

  • Karena desain Pengirim CAF dipengaruhi oleh Library Pendamping Cast, migrasi dari CCL ke Pengirim CAF sebagian besar melibatkan pemetaan one-to-one class 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 CAF Sender, dengan fungsionalitas yang mirip dengan CCL, menjalankan tanggung jawab untuk mematuhi Checklist Desain Google Cast.
  • Pengirim CAF menyediakan widget yang sesuai dengan persyaratan UX Cast; widget ini mirip dengan yang disediakan oleh CCL.
  • CAF Sender menyediakan callback asinkron yang mirip dengan CCL, untuk melacak status dan mendapatkan data. Tidak seperti CCL, Pengirim CAF tidak menyediakan implementasi dari berbagai metode antarmuka.

Di bagian berikut, kami akan berfokus terutama pada aplikasi berdasarkan VideoCastManager CCL, tetapi dalam banyak kasus, konsep yang sama berlaku untuk DataCastManager.

Dependensi

CCL dan CAF memiliki dependensi yang sama pada {i>support library<i} AppCompat, Pustaka dukungan MediaRouter v7 dan layanan Google Play. Namun, perbedaannya adalah bahwa CAF bergantung pada framework Cast baru yang tersedia di Google Play versi 9.2.0 atau yang lebih baru.

Dalam file build.gradle Anda, hapus dependensi pada 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 secara 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 yang praktis, BaseCastManager.checkGooglePlayServices(activity), untuk memverifikasi bahwa konfigurasi versi layanan Google Play yang tersedia di perangkat. CAF tidak menyediakannya sebagai bagian dari Cast SDK. Ikuti prosedurnya Memastikan Perangkat Memiliki APK layanan Google Play untuk memastikan bahwa APK layanan Google Play yang benar telah diinstal pada perangkat karena pembaruan yang mungkin tidak segera menjangkau semua pengguna.

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

Inisialisasi

Untuk CCL, VideoCastManager.initialize() harus dipanggil di Metode onCreate() instance Aplikasi. Logika ini harus dihapus dari kode class Aplikasi.

Di CAF, langkah inisialisasi eksplisit juga diperlukan untuk Transmisi Google Workspace for Education. 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 CCL VideoCastManager dengan menyediakan singleton yang dapat berinteraksi dengan klien. OptionsProvider mirip dengan CastConfiguration CCL untuk memungkinkan Anda untuk 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 di CAF, CastOptionsProvider berikut 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 implementasi lengkap dari OptionsProvider.

Mendeklarasikan OptionsProvider dalam "application" elemen 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>

Inisialisasi CastContext dengan lambat di setiap metode onCreate Activity (dan 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 penggunaan singleton CastContext:

mCastContext = CastContext.getSharedInstance(this);

Penemuan perangkat

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

Dalam CAF, proses penemuan dimulai dan dihentikan secara otomatis oleh saat aplikasi berada di latar depan dan berpindah ke latar belakang, secara berurutan.

Tombol Cast dan dialog Cast

Seperti halnya CCL, komponen ini disediakan oleh dukungan MediaRouter v7 library.

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

Deklarasi MediaRouteActionProvider di 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"/>

Mirip dengan CCL, ganti metode onCreateOptionMenu() dari setiap Aktivitas, tetapi daripada menggunakan CastManager.addMediaRouterButton, gunakan CastButtonFactory CAF 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

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

Interaksi antara pengirim dan penerima kini direpresentasikan sebagai "sesi". Tujuan Class SessionManager menangani siklus proses sesi dan dimulai secara otomatis dan menghentikan sesi sebagai respons terhadap {i>gesture <i}pengguna: sesi dimulai ketika pengguna memilih perangkat Transmisi dalam dialog Transmisi dan berakhir saat pengguna mengetuk "Stop Casting" di dialog Cast atau saat aplikasi pengirim berakhir.

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

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

Dalam CAF, aplikasi pengirim bisa diberi tahu tentang peristiwa siklus proses sesi dengan mendaftarkan SessionManagerListener dengan SessionManager. Tujuan Callback SessionManagerListener menentukan metode callback untuk semua sesi peristiwa siklus proses.

Metode SessionManagerListener berikut dipetakan dari metode CCL Antarmuka VideoCastConsumer:

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

Deklarasikan class yang mengimplementasikan antarmuka SessionManagerListener dan pindahkan 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 mewakili sesi dengan perangkat Cast. Class ini memiliki metode untuk mengontrol volume perangkat dan keadaan bisu, yang dilakukan CCL BaseCastManager.

Daripada menggunakan CCL VideoCastManager 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 sambungan secara eksplisit dari perangkat Transmisi, 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 di 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 callback metode di Cast.Listener; pemroses ini terdaftar dengan CastSession. Semua notifikasi status perangkat lainnya dikirimkan melalui Callback CastStateListener; pemroses ini terdaftar dengan CastSession. Pastikan Anda tetap membatalkan pendaftaran pemroses saat fragmen, aktivitas, atau aplikasi akan beralih ke latar belakang.

Logika menghubungkan kembali

CAF berupaya untuk menghubungkan kembali koneksi jaringan yang hilang karena kehilangan sinyal WiFi sementara atau kesalahan jaringan lainnya. Hal ini sekarang dilakukan di tingkat sesi; sesi dapat masuk ke status "suspended" status ketika koneksi hilang, dan akan beralih kembali ke model "terhubung" status ketika konektivitas dipulihkan. Framework ini akan menangani koneksi kembali ke aplikasi penerima dan menghubungkan kembali saluran Cast sebagai bagian dari proses ini.

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

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

Anda juga tidak memerlukan izin berikut dalam manifes untuk logika penyambungan 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 melanjutkan sesi otomatis yang diaktifkan oleh default (dan dapat dinonaktifkan melalui CastOptions). Jika aplikasi pengirim dikirim ke latar belakang atau dihentikan (dengan menggeser atau karena tabrakan) saat sesi Cast sedang berlangsung, framework akan mencoba melanjutkannya sesi saat aplikasi pengirim kembali ke latar depan atau diluncurkan kembali; ini ditangani secara otomatis oleh SessionManager, yang akan mengeluarkan callback yang sesuai pada setiap instance SessionManagerListener yang terdaftar.

Pendaftaran saluran khusus

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

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

Cara pembuatan saluran khusus ini tidak didukung oleh CAF -- Anda harus mengikuti prosedur Menambahkan Saluran Khusus untuk aplikasi pengirim.

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

Kontrol media

Dalam CAF, class RemoteMediaClient setara dengan VideoCastManager metode media. RemoteMediaClient.Listener setara dengan Metode VideoCastConsumer. Secara khusus, model onRemoteMediaPlayerMetadataUpdated dan onRemoteMediaPlayerStatusUpdated metode VideoCastConsumer dipetakan ke onMetadataUpdated dan Metode onStatusUpdated dari RemoteMediaClient.Listener:

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 menginisialisasi atau mendaftarkan RemoteMediaClient secara eksplisit object; kerangka kerja akan secara otomatis membuat instance objek dan mendaftarkan yang mendasari saluran media pada waktu mulai sesi jika aplikasi penerima terhubung dengan ruang nama media.

RemoteMediaClient dapat diakses sebagai metode getRemoteMediaClient objek CastSession.

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

Alih-alih CCL:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Sekarang gunakan CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

Sejumlah pemroses dapat didaftarkan dengan RemoteMediaClient, yang memungkinkan beberapa komponen pengirim untuk berbagi satu instance RemoteMediaClient yang terkait dengan sesi.

VideoCastManager CCL menyediakan metode untuk menangani pemutaran media:

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

Solusi ini sekarang diimplementasikan oleh RemoteMediaClient di CAF:

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

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

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

Untuk memuat media di CCL, VideoCastManager digunakan:

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

Dalam 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 memberikan tampilan kustom IntroductoryOverlay untuk ditandai tombol Cast saat pertama kali ditampilkan kepada pengguna.

Sebagai ganti menggunakan metode VideoCastConsumer onCastAvailabilityChanged CCL untuk mengetahui waktu menampilkan overlay, deklarasikan CastStateListener untuk menentukan saat tombol Cast terlihat setelah perangkat Cast ditemukan di jaringan lokal dengan 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 guna mengetahui kode kerja lengkap untuk menampilkan overlay pengantar.

Untuk menyesuaikan gaya overlay pendahuluan, ikuti prosedurnya Sesuaikan Overlay Pengantar.

Pengontrol mini

Sebagai ganti MiniController CCL, gunakan MiniControllerFragment CAF di file tata letak aplikasi aktivitas tempat Anda ingin menampilkan pengontrol:

<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 Sesuaikan 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 berikut dari manifes:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL mendukung penyediaan layanan notifikasi khusus 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 kunci kontrol layar 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. Perhatikan juga 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 menggunakan registerLifecycleCallbacksBeforeIceCreamSandwich(); CCL Panggilan VideoCastManager incrementUiCounter dan decrementUiCounter harus dihapus.)

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

Pengontrol yang diperluas

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

Anda dapat menghapus deklarasi VideoCastControllerActivity dalam manifes.

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

Untuk menyesuaikan gaya dan tombol yang ditampilkan dalam pengontrol, ikuti prosedurnya Sesuaikan Pengontrol yang Diperluas.

Fokus audio

Seperti halnya CCL, fokus audio dikelola secara otomatis.

Kontrol volume

Untuk Gingerbread, dispatchKeyEvent diperlukan seperti pada CCL. Di ICS dan yang lebih baru untuk kontrol volume CCL dan CAF ditangani secara otomatis.

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

Teks tertutup

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

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

TracksChooserDialog CCL tidak lagi diperlukan sejak mengubah variabel yang ditutup trek teks ditangani oleh UI pengontrol yang diperluas.

API pemberian teks tertutup pada 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 for Android (uamp) dari CCL ke CAF.

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