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

通过以下过程,您可以将 Android 发送端应用从 Cast SDK v2 转换为 CAF 发送端,后者基于 CastContext 单例。

Cast CAF 发送端 SDK 使用 CastContext 代表您管理 GoogleAPIClient。 CastContext 会为您管理生命周期、错误和回调,这大大 简化了 Cast 应用的开发。

简介

  • CAF 发送端仍使用 Android SDK 管理器作为 Google Play 服务的一部分进行分发
  • 添加了新的软件包,负责遵守 Google Cast 设计核对清单 (com.google.android.gms.cast.framework.*)
  • CAF 发送端提供了符合 Cast 用户体验要求的微件; v2 未提供任何界面组件,并且要求您实现这些 微件。
  • 使用 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"/>

使用 CastButtonFactory 替换每个 Activity 的 onCreateOptionMenu() 方法,以将 MediaRouteButton 连接到 Cast 框架:

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 设备时,会话会启动;当用户在“投射”对话框中点按“停止投射”按钮或发送端应用本身终止时,会话会结束。发送端 应用可以通过向 SessionManager 注册 SessionManagerListener 来接收会话生命周期事件的通知。SessionManagerListener 回调为 回调方法定义所有会话生命周期事件。

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

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

在 CAF 中,音量/静音状态更改通知仍通过 callback methods in the Cast.Listener 中的回调方法传递;这些监听器已向 CastSession 注册。 所有剩余的设备状态通知都通过 CastStateListener 回调传递;这些监听器已向 CastSession 注册。请确保在关联的 fragment、activity 或应用进入后台时,您 仍然会取消注册监听器。

重新连接逻辑

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

此外,CAF 还添加了自动会话恢复功能,该功能默认处于启用状态(可以通过 停用)。CastOptions如果发送端应用在 Cast 会话进行期间被发送到后台或终止(通过滑动关闭或因崩溃),则框架会在发送端应用返回到前台或重新启动时尝试恢复该会话;这由 SessionManager 自动处理,它会在任何已注册的 SessionManagerListener 实例上发出适当的回调。

自定义通道注册

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

媒体控件

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

可以通过 CastSession 对象的 getRemoteMediaClient 方法访问 RemoteMediaClient

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

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

v2 RemoteMediaPlayer 会通过 RemoteMediaPlayer.OnStatusUpdatedListener发送有关 Web 接收器上的媒体 播放器状态更改的通知。

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

在 v2 中,发送端应用必须承担使用户 界面与 Web 接收器上的媒体播放器状态保持同步的负担。

在 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 添加了一个预构建的展开的控制器微件 ExpandedControllerActivity ,您可以直接将其添加到应用中。您不再需要 使用 UIMediaController 实现自定义展开的控制器。

音频焦点

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

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

调试日志记录

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

示例应用

我们提供了使用 CAF 的 Codelab 教程示例应用