O procedimento a seguir permite converter seu app de remetente Android do SDK do Cast v2 para o CAF Sender, que é baseado no Singleton CastContext.
O SDK do Cast CAF Sender 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 de transmissão.
Introdução
- O CAF Sender ainda é distribuído como parte do Google Play Services usando o Android SDK Manager.
- Foram adicionados novos pacotes que assumem a responsabilidade de obedecer à
lista de verificação de design do Google Cast (
com.google.android.gms.cast.framework.*
) - O CAF Sender oferece widgets que atendem aos requisitos de UX do Cast. A v2 não fornece componentes de IU e exigia a implementação desses widgets.
- O uso do GoogleApiClient não é mais necessário para a API Cast.
- A legendagem no CAF Sender é 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 compatível com o CAF é a 9 (Gingerbread).
Inicialização
No CAF, uma etapa de inicialização explícita é necessária para o framework do Google Cast. Isso
envolve a inicialização do Singleton
CastContext
, usando um OptionsProvider
apropriado para especificar o ID do aplicativo receptor da Web e quaisquer 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 plano e vai para o segundo plano,
respectivamente. MediaRouteSelector
e MediaRouter.Callback
não podem ser
usados.
Botão "Transmitir" 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 um
ActionBar
ou um
Toolbar
)
como um item no 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 "Transmitir" é exibida automaticamente.
Controle do dispositivo
No CAF, o controle de dispositivos é amplamente gerenciado pelo framework. O aplicativo
remetente não precisa processar (e não deve tentar) a conexão com
o dispositivo e a inicialização do aplicativo receptor da Web usando
GoogleApiClient
. A interação entre o remetente e o receptor da Web agora é representada
como uma "sessão". A classe
SessionManager
processa o ciclo de vida da sessão, iniciando e interrompendo automaticamente as sessões
em resposta a gestos do usuário: uma sessão é iniciada quando o usuário seleciona um dispositivo
de transmissão na caixa de diálogo de transmissão e é encerrada quando o usuário toca no botão "Parar transmissão"
na caixa de diálogo ou quando o app remetente é encerrado. O aplicativo
remetente pode ser notificado sobre os eventos de ciclo de vida da sessão registrando um
SessionManagerListener
com o SessionManager
. Os callbacks SessionManagerListener
definem
métodos de callback para todos os eventos de 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, o que era feito anteriormente na v2
usando métodos em Cast.CastApi
.
Na v2, os callbacks de
Cast.Listener
foram enviadas notificações de mudanças no estado do dispositivo, incluindo
volume, estado de som desativado, status de espera etc.
No CAF, as notificações de mudança de estado de volume/silêncio 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 restantes do dispositivo são entregues por callbacks
CastStateListener
.
Esses listeners são registrados com o CastSession
. Não deixe de
cancelar o registro dos listeners quando os fragmentos, atividades ou apps associados forem
para o segundo plano.
Lógica de reconexão
Como na v2, o CAF tenta restabelecer conexões de rede que foram perdidas devido à perda temporária de sinal Wi-Fi ou a 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 voltará para o estado "conectada" quando a conectividade for restaurada. O framework se encarrega de se reconectar ao aplicativo Web Receiver e reconectar todos os canais de transmissão 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 por
CastOptions
.
Se o aplicativo remetente for enviado para o segundo plano ou for encerrado (por
deslizamento ou devido a uma falha) enquanto uma sessão de transmissão 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 emite os callbacks apropriados em todas as instâncias
SessionManagerListener
registradas.
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 via Cast.CastApi.setMessageReceivedCallbacks
.
Consulte a seção a seguir para saber mais.
Controle de mídia
A classe v2
RemoteMediaPlayer
foi descontinuada e não pode ser usada. No CAF, ela é substituída pela nova classe
RemoteMediaClient
, que fornece funcionalidade equivalente em uma API mais conveniente. Não é
necessário inicializar ou registrar explicitamente esse objeto. O framework
instanciará automaticamente o objeto e registrará o canal de mídia
subjacente no horário de início da sessão se o aplicativo receptor da Web que está sendo conectado
oferecer suporte ao 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
com um callback
PendingResult
,
que pode ser usado para acompanhar o progresso e o resultado da
solicitação.
O RemoteMediaPlayer
da v2 enviaria notificações sobre mudanças no estado
do player de mídia no receptor da Web pelo
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 do remetente compartilhem a
única instância de RemoteMediaClient
associada à sessão.
Na v2, o aplicativo remetente tinha a responsabilidade de manter a interface do usuário sincronizada com o estado do player de mídia no receptor da Web.
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 fornece uma visualização personalizada
IntroductoryOverlay
para destacar o botão Transmitir quando ele for exibido aos usuários pela primeira vez.
Minicontrole
Na v2, é necessário implementar um minicontrole do zero no app remetente.
No CAF, o SDK fornece 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 fornece 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 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, você precisa implementar um controlador 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 controle expandido pré-criado
ExpandedControllerActivity
,
que você pode simplesmente adicionar ao seu 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 registro.
Apps de exemplo
Temos tutoriais de codelab e apps de exemplo que usam o CAF.