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.