O procedimento a seguir permite converter seu app remetente do Android do Cast SDK v2 para o remetente do CAF, que é baseado no CastContext singleton.
O SDK do remetente do CAF do Cast usa o CastContext para gerenciar o GoogleAPIClient em seu nome. O CastContext gerencia ciclos de vida, erros e callbacks para você, o que simplifica muito o desenvolvimento de um app Cast.
Introdução
- O remetente do CAF ainda é distribuído como parte do Google Play Services usando o SDK Manager do Android.
- Novos pacotes foram adicionados para assumir a responsabilidade de obedecer à lista de verificação de design do Google Cast (
com.google.android.gms.cast.framework.*). - O remetente do CAF oferece widgets que obedecem aos requisitos de UX do Cast. A v2 não forneceu componentes de interface e exigiu que você implementasse esses widgets.
- O uso do GoogleApiClient não é mais necessário para usar a API Cast.
- A legendagem descritiva no remetente do CAF é semelhante à v2.
Dependências
A v2 e o CAF têm as mesmas dependências nas bibliotecas de suporte e no Google Play Services (9.2.0 ou mais recente), conforme descrito no Guia de recursos da biblioteca de suporte.
A versão mínima do SDK do Android com suporte do CAF é a 9 (Gingerbread).
Inicialização
No CAF, uma etapa de inicialização explícita é necessária para o framework do Cast. Isso envolve a inicialização do singleton CastContext, usando um OptionsProvider adequado para especificar o ID do aplicativo Web Receiver e outras opções globais.
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 o OptionsProvider na tag "application" do arquivo AndroidManifest.xml do app:
<application>
...
<meta-data
android:name=
"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
</application>
Inicialize lentamente o CastContext no método onCreate de cada atividade:
private CastContext mCastContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_browser);
setupActionBar();
mCastContext = CastContext.getSharedInstance(this);
}
Essas etapas não eram necessárias na v2.
Descoberta de dispositivos
No CAF, o processo de descoberta é iniciado e interrompido automaticamente pelo framework quando o app passa para o primeiro plano e para o segundo plano, respectivamente. MediaRouteSelector e MediaRouter.Callback não devem ser usados.
Botão e caixa de diálogo "Transmitir"
Como na v2, esses componentes são fornecidos pela biblioteca de suporte MediaRouter.
O botão "Transmitir" ainda é implementado pelo MediaRouteButton e pode ser adicionado à sua atividade (usando uma ActionBar ou uma Toolbar), como um item de 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"/>
Substitua o método onCreateOptionMenu() de cada atividade usando CastButtonFactory para conectar o MediaRouteButton ao framework do 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;
}
Quando alguém toca no botão, a caixa de diálogo "Transmitir" é apresentada automaticamente.
Controle do dispositivo
No CAF, o controle do dispositivo é amplamente processado pelo framework. O aplicativo remetente não precisa processar (e não deve tentar processar) a conexão com o dispositivo e iniciar o aplicativo Web Receiver usando GoogleApiClient. A interação entre o remetente e o Web Receiver agora é representada como uma "sessão". A classe
SessionManager
processa o ciclo de vida da sessão e inicia e interrompe automaticamente as sessões
em resposta a gestos do usuário: uma sessão é iniciada quando o usuário seleciona um dispositivo Cast
na caixa de diálogo "Transmitir" e é encerrada quando o usuário toca no botão "Parar transmissão"
na caixa de diálogo "Transmitir" ou quando o próprio app remetente é encerrado. O remetente
aplicativo pode ser notificado sobre eventos do ciclo de vida da sessão registrando um
SessionManagerListener
com o SessionManager. Os callbacks SessionManagerListener definem métodos de callback para todos os eventos do ciclo de vida da sessão.
A classe
CastSession
representa uma sessão com um dispositivo de transmissão. A classe tem métodos para controlar o volume do dispositivo e os estados de mudo, que eram feitos anteriormente na v2 usando métodos em Cast.CastApi.
Na v2, os
Cast.Listener
callbacks forneciam notificações de mudanças no estado do dispositivo, incluindo
volume, estado de mudo, status de espera e assim por diante.
No CAF, as notificações de mudança de estado de volume/mudo ainda são entregues por métodos de callback
no Cast.Listener. Esses listeners são registrados com
CastSession.
Todas as notificações de estado do dispositivo restantes são entregues por
CastStateListener
callbacks. Esses listeners são registrados com o CastSession. Verifique se você ainda cancela o registro de listeners quando os fragmentos, atividades ou apps associados passam para o segundo plano.
Lógica de reconexão
Assim como na v2, o CAF tenta restabelecer conexões de rede perdidas devido à perda temporária do sinal Wi-Fi ou outros erros de rede. Isso agora é feito no nível da sessão. Uma sessão pode entrar em um estado "suspenso" quando a conexão é perdida e volta para um estado "conectado" quando a conectividade é restaurada. O framework cuida da reconexão ao aplicativo Web Receiver e da reconexão de todos os canais do Cast como parte desse processo.
Além disso, o CAF também adiciona a retomada automática da sessão, que é ativada por
padrão e pode ser desativada usando
CastOptions.
Se o aplicativo remetente for enviado para o segundo plano ou encerrado (deslizando ou devido a uma falha) enquanto uma sessão do Cast estiver em andamento, o framework vai tentar retomar essa sessão quando o aplicativo remetente retornar ao primeiro plano ou for reiniciado. Isso é processado automaticamente pelo SessionManager, que vai emitir os callbacks adequados em todas as instâncias SessionManagerListener registradas.
Registro de canal personalizado
Na v2, os canais personalizados (implementados usando
Cast.MessageReceivedCallback)
são registrados com a Cast.CastApi. No CAF, os canais personalizados são registrados com a instância CastSession. O registro pode ser feito no
SessionManagerListener.onSessionStarted
método de callback. Para aplicativos de mídia, não é mais necessário registrar explicitamente o canal de controle de mídia usando Cast.CastApi.setMessageReceivedCallbacks. Consulte a seção a seguir para mais detalhes.
Controle de mídia
A classe da v2
RemoteMediaPlayer
foi descontinuada e não deve ser usada. No CAF, ela é substituída pela nova
RemoteMediaClient
classe, que oferece funcionalidade equivalente em uma API mais conveniente. Não é necessário inicializar ou registrar explicitamente esse objeto. O framework vai instanciar automaticamente o objeto e registrar o canal de mídia subjacente no horário de início da sessão se o aplicativo Web Receiver ao qual está conectado oferecer suporte ao namespace de mídia.
O RemoteMediaClient pode ser acessado como o
getRemoteMediaClient método do objeto CastSession.
Na v2, todas as solicitações de mídia emitidas no RemoteMediaPlayer retornariam um
RemoteMediaPlayer.MediaChannelResult por um PendingResult callback.
No CAF, todas as solicitações de mídia emitidas no RemoteMediaClient retornam um
RemoteMediaClient.MediaChannelResult
por um
PendingResult
callback que pode ser usado para acompanhar o progresso e o resultado final da
solicitação.
O v2 RemoteMediaPlayer enviaria notificações sobre mudanças no estado do player de mídia no Web Receiver usando o
RemoteMediaPlayer.OnStatusUpdatedListener.
No CAF, o RemoteMediaClient fornece callbacks equivalentes pela
RemoteMediaClient.Listener
interface. Qualquer número de listeners pode ser registrado com o RemoteMediaClient, o que permite que vários componentes remetentes compartilhem a única instância de RemoteMediaClient associada à sessão.
Na v2, o aplicativo remetente precisava manter a interface do usuário sincronizada com o estado do player de mídia no Web Receiver.
No CAF, a classe
UIMediaController
assume a maior parte dessa responsabilidade.
Sobreposição introdutória
A v2 não fornece uma interface de sobreposição introdutória.
O CAF oferece uma visualização personalizada
IntroductoryOverlay
para destacar o botão "Transmitir" quando ele for mostrado aos usuários pela primeira vez.
Minicontrole
Na v2, é necessário implementar um minicontrole do zero no app remetente.
No CAF, o SDK oferece uma visualização personalizada,
MiniControllerFragment,
que pode ser adicionada ao arquivo de layout do app das atividades em que
você quer mostrar o minicontrole.
Notificação e tela de bloqueio
Na v2, os controladores de notificação e tela de bloqueio não são fornecidos pelo SDK. Para esse SDK, é necessário criar esses recursos no app remetente usando as APIs do framework do Android.
No CAF, o SDK oferece um
NotificationsOptions.Builder
para ajudar a criar controles de mídia para a notificação e a tela de bloqueio
no app remetente. Os controles de notificação e tela de bloqueio podem ser ativados
com as
CastOptions
ao inicializar o 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();
}
Controle expandido
Na v2, é necessário implementar um controle expandido do zero no app remetente.
O CAF oferece uma
UIMediaController
classe auxiliar que facilita a criação do seu próprio controle expandido.
O CAF adiciona um widget de controle expandido pré-criado
ExpandedControllerActivity
que pode ser adicionado ao seu app. Não é mais necessário
implementar um controle expandido personalizado usando UIMediaController.
Seleção de áudio
Na v2, é necessário usar MediaSessionCompat para gerenciar a seleção de áudio.
No CAF, a seleção de áudio é gerenciada automaticamente.
Registros de depuração
No CAF, não há opções de registro.
Apps de exemplo
Temos tutoriais de codelab e apps de exemplo que usam o CAF.