将 Android Sender 应用从 Cast SDK v2 迁移到 Cast 应用框架 (CAF)

以下步骤可让您将 Android 发送器应用从 Cast SDK v2 转换为基于 CastContext 单例的 CAF 发送器。

Cast CAF Sender SDK 使用 CastContext 代表您管理 GoogleAPIClient。 CastContext 可为您管理生命周期、错误和回调,从而大大简化 Cast 应用的开发。

简介

  • CAF 发送者仍作为 Google Play 服务的一部分通过 Android SDK 管理器进行分发
  • 添加了负责遵守 Google Cast 设计核对清单 (com.google.android.gms.cast.framework.*) 的新软件包
  • CAF Sender 提供符合 Cast 用户体验要求的 widget;v2 未提供任何界面组件,要求您实现这些 widget。
  • 使用 Cast API 时不再需要使用 GoogleApiClient。
  • CAF 发送方中的字幕与 v2 类似。

依赖项

V2 和 CAF 对支持库和 Google Play 服务(9.2.0 或更高版本)的依赖关系如支持库功能指南中所述

CAF 支持的最低 Android SDK 版本是 9 (Gingerbread)。

初始化

在 CAF 中,需要对 Cast 框架执行显式初始化步骤。这涉及初始化 CastContext 单例,使用适当的 OptionsProvider 指定 Web 接收器应用 ID 和任何其他全局选项。

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

在应用 AndroidManifest.xml 文件的“application”标记内声明 OptionsProvider

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

在每个 activity 的 onCreate 方法中延迟初始化 CastContext

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

在 v2 中已没有必要执行这些步骤。

设备发现

在 CAF 中,当应用进入前台和转到后台时,框架会分别自动启动和停止发现过程。不应使用 MediaRouteSelectorMediaRouter.Callback

“投放”按钮和“投放”对话框

与在 v2 中一样,这些组件由 MediaRouter 支持库提供。

“投射”按钮仍由 MediaRouteButton 实现,并可作为菜单中的菜单项添加到 activity(使用 ActionBarToolbar)。

<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"/>

使用 CastButtonFactoryMediaRouteButton 连接到 Cast 框架,从而替换每个 Activity 的 onCreateOptionMenu() 方法:

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

当有人点按该按钮时,系统会自动显示“投放”对话框。

设备控制

在 CAF 中,设备控制主要由框架处理。发送方应用不需要处理(也不应尝试处理)连接到设备并使用 GoogleApiClient 启动 Web 接收器应用的行为。发送者和 Web 接收器之间的互动现在以“会话”的形式表示。SessionManager 类会处理会话生命周期,并自动启动和停止会话以响应用户手势:当用户在 Cast 对话框中选择 Cast 设备时,会启动会话;当用户点按 Cast 对话框中的“Stop Cast”按钮或发送发送应用本身终止时,会话就会结束。向发送者应用发送会话生命周期事件通知,方法是向 SessionManager 注册 SessionManagerListenerSessionManagerListener 回调会为所有会话生命周期事件定义回调方法。

CastSession 类表示与 Cast 设备的会话。此类具有用于控制设备音量和静音状态的方法,而以前在 v2 中会使用 Cast.CastApi 上的方法完成这些操作。

在 v2 中,Cast.Listener 回调提供了有关设备状态更改的通知,包括音量、静音状态、待机状态等。

在 CAF 中,音量/静音状态变化通知仍通过 Cast.Listener 中的回调方法传送;这些监听器通过 CastSession 注册。其余的所有设备状态通知都通过 CastStateListener 回调进行传送;这些监听器通过 CastSession 注册。确保仍然在关联的 fragment、activity 或应用进入后台时取消注册监听器。

重新连接逻辑

与 v2 一样,CAF 会尝试重新建立因 Wi-Fi 信号暂时丢失或其他网络错误而丢失的网络连接。此操作现在在会话级别完成;会话在连接中断时可以进入“挂起”状态,并在连接恢复时转换回“已连接”状态。在此过程中,框架会负责重新连接到网络接收器应用,并重新连接任何 Cast 频道。

此外,CAF 还添加了自动会话恢复功能,该功能默认处于启用状态(可通过 CastOptions 停用)。如果在 Cast 会话正在进行时,发送器应用被发送到后台或终止(因滑动操作或崩溃而终止),框架会在发送器应用返回前台或重新启动时尝试恢复该会话;此过程由 SessionManager 自动处理,它将对所有已注册的 SessionManagerListener 实例发出适当的回调。

自定义渠道注册

在 v2 中,自定义渠道(使用 Cast.MessageReceivedCallback 实现)通过 Cast.CastApi 注册。在 CAF 中,自定义渠道则改为向 CastSession 实例注册。您可以通过 SessionManagerListener.onSessionStarted 回调方法完成注册。对于媒体应用,不再需要通过 Cast.CastApi.setMessageReceivedCallbacks 明确注册媒体控制通道;如需了解详情,请参阅以下部分。

媒体控件

v2 类 RemoteMediaPlayer 已被弃用,不应继续使用。在 CAF 中,它已被新的 RemoteMediaClient 类取代,后者在更方便的 API 中提供了等效的功能。无需显式初始化或注册此对象;如果连接的 Web 接收器应用支持媒体命名空间,则框架会自动在会话启动时实例化该对象并注册底层媒体频道。

RemoteMediaClient 可作为 CastSession 对象的 getRemoteMediaClient 方法进行访问。

在 v2 中,在 RemoteMediaPlayer 上发出的所有媒体请求都将通过 PendingResult 回调返回 RemoteMediaPlayer.MediaChannelResult

在 CAF 中,在 RemoteMediaClient 上发出的所有媒体请求都会通过 PendingResult 回调返回一个 RemoteMediaClient.MediaChannelResult,该回调可用于跟踪请求的进度和最终结果。

v2 RemoteMediaPlayer 将通过 RemoteMediaPlayer.OnStatusUpdatedListener 发送有关网络接收器上媒体播放器状态变化的通知。

在 CAF 中,RemoteMediaClient 通过其 RemoteMediaClient.Listener 接口提供等效回调。您可以向 RemoteMediaClient 注册任意数量的监听器,这使得多个发送者组件可以共享与会话关联的单个 RemoteMediaClient 实例。

在 v2 中,发送方应用必须承担确保界面与网络接收器上的媒体播放器状态保持同步的责任。

在 CAF 中,UIMediaController 类承担大部分此类责任。

介绍性叠加层

V2 不提供介绍性叠加层界面。

CAF 提供了一个自定义视图 IntroductoryOverlay,用于在首次向用户显示“投射”按钮时突出显示该按钮。

迷你控制器

在 v2 中,您需要在发送器应用中从头开始实现迷你控制器。

在 CAF 中,SDK 提供了自定义视图 MiniControllerFragment,您可以将该视图添加到要在其中显示迷你控制器的 activity 的应用布局文件。

通知和锁定屏幕

在 v2 中,通知和锁定屏幕的控制器不是由 SDK 提供。对于该 SDK,您需要使用 Android 框架 API 将这些功能内置到发送器应用中。

在 CAF 中,SDK 提供了 NotificationsOptions.Builder,可帮助您将通知和锁定屏幕的媒体控件构建到发送器应用中。您可以在初始化 CastContext 时使用 CastOptions 启用通知和锁定屏幕控件。

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

展开的控制器

在 v2 中,您需要在发送器应用中从头开始实现展开的控制器。

CAF 提供了一个 UIMediaController 辅助类,可让您轻松构建自己的扩展控制器。

CAF 添加了预构建的展开控制器 widget ExpandedControllerActivity,您只需将其添加到应用中。您不再需要使用 UIMediaController 实现自定义展开控制器。

音频焦点

在 v2 中,您需要使用 MediaSessionCompat 来管理音频焦点。

在 CAF 中,系统会自动管理音频焦点。

调试日志记录

在 CAF 中,没有日志记录选项。

示例应用

我们有 Codelab 教程和使用 CAF 的示例应用