The following procedure enables you to convert your Android sender app from Cast SDK v2 to CAF Sender, which is based on the CastContext singleton.
The Cast CAF Sender SDK uses CastContext to manage the GoogleAPIClient on your behalf. CastContext manages lifecycles, errors and callbacks for you, which greatly simplifies developing a Cast app.
Introduction
- CAF Sender is still distributed as part of Google Play services using the Android SDK manager
- New packages have been added that take on responsibility for complying with
the Google Cast Design checklist (
com.google.android.gms.cast.framework.*
) - CAF Sender provides widgets that comply with the Cast UX requirements; v2 did not provide any UI components and required you to implement these widgets.
- Use of GoogleApiClient is no longer required for using the Cast API.
- Closed captioning in CAF Sender is similar to v2.
Dependencies
V2 and CAF have the same dependencies on the support libraries and Google Play services (9.2.0 or later) as described at the Support Library Features Guide
The minimum Android SDK version that CAF supports is 9 (Gingerbread).
Initialization
In CAF, an explicit initialization step is required for the Cast framework. This
involves initializing the
CastContext
singleton, using an appropriate
OptionsProvider
to specify the Web Receiver application ID and any other global options.
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;
}
}
Declare the OptionsProvider
within the "application" tag of the app
AndroidManifest.xml
file:
<application>
...
<meta-data
android:name=
"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
</application>
Lazily initialize the CastContext
in each Activity’s onCreate
method:
private CastContext mCastContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_browser);
setupActionBar();
mCastContext = CastContext.getSharedInstance(this);
}
These steps were not necessary in v2.
Device discovery
In CAF, the discovery process is started and stopped automatically by the
framework when the app comes to the foreground and goes to the background,
respectively. MediaRouteSelector
and MediaRouter.Callback
should not be
used.
Cast button and Cast dialog
As in v2, these components are provided by the MediaRouter support library.
The Cast button is still implemented by the
MediaRouteButton
and can be added to your activity (using either an
ActionBar
or a
Toolbar
),
as a menu item in your menu.
<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"/>
Override the onCreateOptionMenu()
method of each Activity by using
CastButtonFactory
to wire up the MediaRouteButton
to the Cast framework:
private MenuItem mediaRouteMenuItem;
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
mediaRouteMenuItem =
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
menu,
R.id.media_route_menu_item);
return true;
}
When someone taps the button, the Cast dialog is automatically presented.
Device control
In CAF, device control is largely handled by the framework. The sender
application does not need to handle (and should not try to handle) connecting to
the device and launching the Web Receiver application using
GoogleApiClient
. Interaction between sender and Web Receiver is now represented
as a "session". The
SessionManager
class handles the session lifecycle and automatically starts and stops sessions
in response to user gestures: a session is started when the user selects a Cast
device in the Cast dialog and is ended when the user taps the "Stop Casting"
button in the Cast dialog or when the sender app itself terminates. The sender
application can be notified of session lifecycle events by registering a
SessionManagerListener
with the SessionManager
. The SessionManagerListener
callbacks define
callback methods for all session lifecycle events.
The
CastSession
class represents a session with a Cast device. The class has methods for
controlling the device volume and mute states, which was previously done in v2
using methods on Cast.CastApi
.
In v2, the
Cast.Listener
callbacks provided notifications of changes to the device state, including
volume, mute state, standby status, and so forth.
In CAF, volume/mute state change notifications are still delivered via callback
methods in the Cast.Listener
; these listeners are registered with
CastSession
.
All of the remaining device state notifications are delivered via
CastStateListener
callbacks; these listeners are registered with the CastSession
. Make sure you
still unregister listeners when the associated fragments, activities or apps go
to the background.
Reconnection logic
As with v2, CAF attempts to re-establish network connections that are lost due to temporary WiFi signal loss or other network errors. This is now done at the session level; a session can enter a "suspended" state when the connection is lost, and will transition back to a "connected" state when connectivity is restored. The framework takes care of reconnecting to the Web Receiver application and reconnecting any Cast channels as part of this process.
In addition, CAF also adds automatic session resumption which is enabled by
default (and can be deactivated via
CastOptions
.
If the sender application is sent to the background or is terminated (by
swiping-away or because of a crash) while a Cast session is in progress, the
framework will attempt to resume that session when the sender application
returns to the foreground or is relaunched; this is handled automatically by the
SessionManager
, which will issue the appropriate callbacks on any registered
SessionManagerListener
instances.
Custom channel registration
In v2, custom channels (implemented using
Cast.MessageReceivedCallback
)
are registered with the Cast.CastApi
. In CAF, custom channels are instead registered with the
CastSession
instance. The registration can be done in the
SessionManagerListener.onSessionStarted
callback method. For media applications, it is no longer necessary to explicitly
register the media control channel via Cast.CastApi.setMessageReceivedCallbacks
;
see the following section for more details.
Media control
The v2 class
RemoteMediaPlayer
is deprecated and should not be used. In CAF, it is superseded by the new
RemoteMediaClient
class, which provides equivalent functionality in a more convenient API. It is
not necessary to explicitly initialize or register this object; the framework
will automatically instantiate the object and register the underlying media
channel at session start time if the Web Receiver application being connected to
supports the media namespace.
The RemoteMediaClient
can be accessed as the
getRemoteMediaClient
method of the CastSession
object.
In v2, all media requests issued on the RemoteMediaPlayer
would return a
RemoteMediaPlayer.MediaChannelResult
via a PendingResult
callback.
In CAF, all media requests issued on the RemoteMediaClient
return a
RemoteMediaClient.MediaChannelResult
via a
PendingResult
callback which can be used to track the progress and eventual outcome of the
request.
The v2 RemoteMediaPlayer
would send notifications about changes in the media
player state on the Web Receiver via the
RemoteMediaPlayer.OnStatusUpdatedListener
.
In CAF, the RemoteMediaClient
provides equivalent callbacks via its
RemoteMediaClient.Listener
interface. Any number of listeners can be registered with the
RemoteMediaClient
, which allows multiple sender components to share the
single instance of RemoteMediaClient
that is associated with the session.
In v2, the sender application had to take on the burden of keeping the user interface in sync with the media player state on the Web Receiver.
In CAF, the class
UIMediaController
takes on most of this responsibility.
Introductory overlay
V2 does not provide an introductory overlay UI.
CAF provides a custom view
IntroductoryOverlay
to highlight the Cast button when it is first shown to users.
Mini controller
In v2, you need to implement a mini controller from scratch in the sender app.
In CAF, the SDK provides a custom view,
MiniControllerFragment
,
which you can add to the app layout file of the activities in which
you want to show the mini controller.
Notification and lock screen
In v2, controllers for notification and lock screen are not provided by the SDK. For that SDK, you need to build these features into your sender app using the Android framework APIs.
In CAF, the SDK provides a
NotificationsOptions.Builder
to help you build media controls for the notification and lock screen
into the sender app. The notification and lock screen controls can be enabled
with the
CastOptions
when initializing the CastContext
.
public CastOptions getCastOptions(Context context) {
NotificationOptions notificationOptions = new NotificationOptions.Builder()
.setTargetActivityClassName(VideoBrowserActivity.class.getName())
.build();
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build();
return new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build();
}
Expanded controller
In v2, you need to implement an expanded controller from scratch in the sender app.
CAF provides a
UIMediaController
helper class that makes it easy for you to build your own expanded
controller.
CAF adds a pre-built expanded controller widget
ExpandedControllerActivity
which you can simply add to your app. You no longer need to
implement a custom expanded controller using UIMediaController
.
Audio focus
In v2, you need to use MediaSessionCompat
to manage audio focus.
In CAF, audio focus is managed automatically.
Debug logging
In CAF there are no logging options.
Sample apps
We have codelab tutorials and sample apps that use CAF.