O procedimento a seguir permite converter seu app remetente do Android do SDK do Cast v2 para o remetente do CAF, que é baseado no singleton CastContext.
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.
- Adicionamos novos pacotes que assumem a responsabilidade de obedecer à lista de verificação de design do Google Cast (
com.google.android.gms.cast.framework.*
). - O remetente do CAF fornece widgets que obedecem aos requisitos de UX do Cast. A v2 não fornecia componentes de UI e exigia que você implementasse esses widgets.
- O uso do GoogleApiClient não é mais necessário para usar a API Cast.
- O closed captioning no CAF Sender é semelhante ao v2.
Dependências
O 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 compatível com o CAF é a 9 (Gingerbread).
Inicialização
No CAF, é necessário uma etapa de inicialização explícita para o framework do Cast. Isso envolve inicializar o 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 entra em primeiro e segundo plano,
respectivamente. MediaRouteSelector
e MediaRouter.Callback
não devem ser usados.
Botão Transmitir e caixa de diálogo Transmitir
Assim como na v2, esses componentes são fornecidos pela biblioteca de suporte do MediaRouter.
O botão Transmitir ainda é implementado pelo
MediaRouteButton
e pode ser adicionado à sua atividade (usando um
ActionBar
ou um
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 Google 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 do Google Cast é apresentada automaticamente.
Controle do dispositivo
No CAF, o controle do dispositivo é feito principalmente pelo framework. O aplicativo
remetente não precisa processar (e não deve tentar processar) a conexão com
o dispositivo e o lançamento do 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 aos gestos do usuário: uma sessão é iniciada quando o usuário seleciona um dispositivo
no diálogo do Google Cast e é encerrada quando o usuário toca no botão "Parar transmissão"
no diálogo do Google Cast ou quando o próprio app remetente é encerrado. O aplicativo
remetente 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 Cast. A classe tem métodos para controlar o volume e os estados de mudo do dispositivo, o que era feito na v2 usando métodos em Cast.CastApi
.
Na v2, os
callbacks Cast.Listener
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/silêncio ainda são entregues por métodos de callback
em Cast.Listener
. Esses listeners são registrados com
CastSession
.
Todas as notificações restantes de estado do dispositivo são enviadas por callbacks
CastStateListener
.
Esses listeners são registrados com o CastSession
. Não se esqueça de
cancelar o registro dos listeners quando os fragmentos, atividades ou apps associados forem
para 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. Agora isso é feito no nível da sessão. Uma sessão pode entrar em um estado "suspensa" quando a conexão é perdida e volta para um estado "conectada" quando a conectividade é restaurada. O framework cuida da reconexão com o aplicativo Web Receiver e de todos os canais do Google Cast como parte desse processo.
Além disso, o CAF também adiciona a retomada automática de sessão, que é ativada por
padrão e pode ser desativada via
CastOptions
.
Se o aplicativo remetente for enviado para segundo plano ou encerrado (por
deslizar para fora ou devido a uma falha) enquanto uma sessão do Cast estiver em andamento, o
framework tentará retomar essa sessão quando o aplicativo remetente
voltar ao primeiro plano ou for reiniciado. Isso é processado automaticamente pelo
SessionManager
, que vai emitir os callbacks apropriados em qualquer
instância SessionManagerListener
registrada.
Registro de canal personalizado
Na v2, os canais personalizados (implementados usando
Cast.MessageReceivedCallback
)
são registrados com o Cast.CastApi
. No CAF, os canais personalizados são registrados com a instância
CastSession
. O registro pode ser feito no método de callback
SessionManagerListener.onSessionStarted
. 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 v2
RemoteMediaPlayer
foi descontinuada e não deve ser usada. No CAF, ela é substituída pela nova classe
RemoteMediaClient
, 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 conectado for compatível com o namespace de mídia.
O RemoteMediaClient
pode ser acessado como o método
getRemoteMediaClient
do objeto CastSession
.
Na v2, todas as solicitações de mídia emitidas no RemoteMediaPlayer
retornariam um
RemoteMediaPlayer.MediaChannelResult
por um callback PendingResult
.
No CAF, todas as solicitações de mídia emitidas no RemoteMediaClient
retornam um
RemoteMediaClient.MediaChannelResult
por um
callback PendingResult
que pode ser usado para acompanhar o progresso e o resultado final da
solicitação.
A v2 RemoteMediaPlayer
enviava notificações sobre mudanças no estado do player de mídia no Web Receiver usando a RemoteMediaPlayer.OnStatusUpdatedListener
.
No CAF, o RemoteMediaClient
fornece callbacks equivalentes pela interface
RemoteMediaClient.Listener
. 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 oferece uma interface de sobreposição introdutória.
O CAF oferece uma visualização personalizada
IntroductoryOverlay
para destacar o botão "Transmitir" quando ele é 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 Android.
No CAF, o SDK oferece um
NotificationsOptions.Builder
para ajudar você a criar controles de mídia para a notificação e a tela de bloqueio
no app remetente. Os controles da notificação e da tela de bloqueio podem ser ativados
com o
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 fornece uma classe auxiliar
UIMediaController
que facilita a criação do seu próprio controlador
expandido.
O CAF adiciona um widget de controlador expandido pré-criado
ExpandedControllerActivity
que pode ser adicionado ao app. Não é mais necessário
implementar um controlador expandido personalizado usando UIMediaController
.
Seleção de áudio
Na v2, você precisa 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 geração de registros.
Apps de exemplo
Temos tutoriais de codelab e apps de exemplo que usam o CAF.