O procedimento a seguir permite que você converta seu app remetente do Android do SDK do Cast v2 para o remetente CAF, 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 com Google Cast.
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 fornece widgets que obedecem aos requisitos do Cast UX. A v2 não fornecia componentes de interface e exigia a implementação desses widgets.
- O uso de GoogleApiClient não é mais necessário para usar a API Cast.
- As legendas no CAF Sender são semelhantes à 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 Cast. Isso
envolve a inicialização do
singleton
CastContext
usando um
OptionsProvider
apropriado para especificar o ID do aplicativo do receptor da Web 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 vai para o segundo plano,
respectivamente. MediaRouteSelector
e MediaRouter.Callback
não podem ser
usados.
Botão "Transmitir" e caixa de diálogo "Transmitir"
Assim 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 à atividade (usando um
ActionBar
ou um
Toolbar
),
como um item de menu 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 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 do dispositivo é principalmente processado pelo framework. O aplicativo
remetente não precisa processar (nem tentar processar) a conexão com
o dispositivo e iniciar o 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 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
de transmissão na caixa de diálogo "Transmitir" e é encerrada quando o usuário toca no botão "Parar transmissão"
na caixa de diálogo ou quando o próprio app remetente é encerrado. O app
remetente pode ser notificado sobre 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 silenciamento, o que era feito anteriormente 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 silenciado, status de espera e assim por diante.
No CAF, as notificações de mudança de estado de volume/silenciamento 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 se esqueça
de cancelar o registro de listeners quando os fragmentos, atividades ou apps associados forem
para o segundo plano.
Lógica de reconexão
Assim como na v2, o CAF tenta restabelecer as conexões de rede perdidas devido à perda temporária do sinal Wi-Fi ou a outros erros de rede. Agora, isso é 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 "conectado" quando a conectividade for restaurada. O framework faz a reconexão ao aplicativo receptor da Web e reconecta todos os canais de transmissão 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 por meio de CastOptions
).
Se o aplicativo remetente for enviado para o segundo plano ou for encerrado (por meio de um
deslizamento ou devido a uma falha) enquanto uma sessão de transmissão estiver em andamento, o
framework tentará retomar essa sessão quando o aplicativo remetente
retornar ao primeiro plano ou for reiniciado. Isso é processado automaticamente pelo
SessionManager
, que 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 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 apps 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 foi 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 o objeto automaticamente e registrar o canal de mídia
no horário de início da sessão se o aplicativo receptor da Web que está sendo conectado tiver
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
com 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 da
solicitação.
O RemoteMediaPlayer
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 usando a
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 precisava 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 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 aplicativo 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 para notificação e tela de bloqueio não são fornecidos pelo SDK. Para esse SDK, você precisa 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 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 geração de registros.
Apps de exemplo
Temos tutoriais do codelab e apps de exemplo que usam o CAF.