保持 Google Cast 接收器处于活动状态 and/or 发送器已连接

Keep Google Cast receiver alive and/or sender connected

我正在为需要执行两项任务的商店编写 Cast 应用程序:

我已经开发了应用程序(自定义接收方和 Android 发送方)。广告由服务器提供,因此嵌入到接收方应用程序中,而发送方应用程序用于控制 "We are serving" 号码。

一切正常,但几分钟后发送方断开连接,接收方退出,屏幕上只剩下 Google Chromecast 背景图片。

虽然我可以接受发送方断开连接(即使我想避免它),但接收方应用退出是不可接受的。

我尝试通过 CastSession.sendMessage() 发送保持活动消息,但没有成功。

我考虑过在隐藏的 cast-media-player 中播放一些内容来欺骗它以为我在播放某些东西,但我认为这是一个非常肮脏的解决方案。

是否有可能以更好的方式实现我想要做的事情?

看看

cast.framework.CastReceiverOptions.maxInactivity

我进一步调查了这个问题,我发现问题是接收方的播放器处于空闲状态的时间太长,因此关闭了应用程序以及与发送方的所有连接。

AFAIK,没有办法以干净的方式避免这种行为,所以我选择了肮脏的解决方案。我在接收器中放置了一个隐藏的 cast-media-player,然后向它发送了一个不存在的图像。它尝试加载图像(进入缓冲状态),但失败了。通过这种方式,它重置了 IDLE 计时器,应用程序不再退出。

我希望这对以后的其他人有所帮助。

编辑:添加了更长的解释

为了解决这个问题,我不得不添加 cast-media-player 标签并通过接收器应用程序中的 CSS 隐藏它:

<head>
    <style>
        cast-media-player {
            display: none;
        }   
    </style>
</head>
<body>
    <!-- My content -->
    <cast-media-player></cast-media-player>
</body>

之后,我向 Android 发送器应用程序添加了一个循环,每 30 秒(即使超时时间更长,它也可能会工作)要求播放器显示给定图像:

private void playFakeContent() {
    final String addr = "http://your.domain.here/404image.png"; 

    CastSession session = mSessionManager.getCurrentCastSession();
    if (null != session) {
        MediaInfo.Builder builder = new MediaInfo.Builder(addr)
                    .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
                    .setContentType("image/png")
                    .setMetadata(new MediaMetadata(MediaMetadata.MEDIA_TYPE_PHOTO));
        session.getRemoteMediaClient().load(builder.build(), true);
    }
}

我还在前台为我的应用程序提供了一项服务,以确保 Android 不会终止我在 phone 上的应用程序。

可能应该有一些改进的余地,例如在给定的时间内播放实际图像以避免无用的 HTTP 请求,以及播放器状态上的侦听器仅在进入空闲状态时才请求图像, 但我现在没有足够的时间尝试。 如果我愿意,我会更新我的答案。

目前我无法分享完整的应用程序代码,但我打算在将来 GitHub 上发布它。我会在项目准备好后立即更新我的答案。

一个更简单的解决方案是在传递给 CastReceiverContext.start() 的 CastReceiverOptions 中设置 disableIdleTimeout: true。这将使您的接收器保持 运行.

示例(内联构造 CastReceiverOptions 的代码):

常量上下文=cast.framework.CastReceiverContext.getInstance(); ... context.start({disableIdleTimeout: true});