I am writing a Cast application for a shop that needs to perform two tasks:
I have already developed the application (both a custom receiver and an Android sender). The ads are provided by the server and therefore embedded in the receiver application, while the sender application is used to control the "We are serving" number.
Everything works like a charm, but after some minutes the sender disconnects and the receiver exits, leaving the screen with the Google Chromecast backdrop images.
While I can accept the sender disconnection (even if I would like to avoid it), the receiver app exiting is not acceptable.
I tried sending keep-alive messages through the CastSession.sendMessage(), but it didn't work.
I thought about playing some content in a hidden cast-media-player to trick it in thinking that I am playing something, but I think this is quite a dirty solution.
Is it possible to achieve what I am trying to do in a better way?
I made further investigation on the issue and I find out that the problem is that the Player in the receiver is in IDLE state for too long and therefore close the application and any connection with the sender.
AFAIK, there is no way to avoid this behavior in a clean way, so I opted for the dirty solution. I put an hidden cast-media-player in the receiver and I send it a non-existent image. It tries to load the image (going in state BUFFERING), but it fails. In this way It reset the IDLE timer and the application doesn't quit anymore.
I hope this will be helpful to someone else in the future.
EDIT: Added longer explanation
In order to make the workaround, I had to add the cast-media-player tag and hide it through the CSS in the receiver application:
<head>
<style>
cast-media-player {
display: none;
}
</style>
</head>
<body>
<!-- My content -->
<cast-media-player></cast-media-player>
</body>
After that I added to the Android sender application a loop that each 30 seconds (probably it would work even with a longer timeout) ask the player to display a given image:
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);
}
}
I also put a service on my application in foreground to ensure that Android won't kill my application on the phone.
There should probably be some room for improvements, for example playing an actual image for a given amount of time to avoid a useless HTTP request and a listener on the Player state to request the image only when it goes in IDLE state, but I didn't have enough time to try it right now. If I ever will, I'll update my answer.
I am not able to share the full application code at this moment, but I have intention to do release it on GitHub in the future. I'll update my answer as soon as the project is ready.