Migrar o app Android remetente do SDK do Cast v2 para o framework do aplicativo de transmissão (CAF, na sigla em inglês)

O procedimento a seguir permite converter o app Android de transmissão do Google Cast do SDK v2 para o remetente CAF, que é baseado no CastContext singleton.

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 é muito simplifica o desenvolvimento de um app com Google Cast.

Introdução

  • O remetente CAF ainda é distribuído como parte do Google Play Services com o Android SDK Manager
  • Foram adicionados novos pacotes que assumem a responsabilidade de cumprir a 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 nenhum componente de interface e exigia a implementação desses componentes 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. do Google (9.2.0 ou posterior), conforme descrito em Recursos da Biblioteca de Suporte Guia

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 da CastContext Singleton, usando uma OptionsProvider 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;
    }
}

Declarar o OptionsProvider no "application" tag do app Arquivo AndroidManifest.xml:

<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 quando o app vai 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"

Como na v2, esses componentes são fornecidos pelo suporte do MediaRouter biblioteca.

O botão Transmitir ainda é implementado pelo MediaRouteButton e podem ser adicionados à 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 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 remetente aplicativo não precisa gerenciar (e não deve tentar) se conectar 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 SessionManager lida com 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 uma transmissão dispositivo na caixa de diálogo "Transmitir" e é finalizada quando o usuário toca no botão "Parar transmissão" na caixa de diálogo "Transmitir" ou quando o próprio app remetente for encerrado. O remetente aplicativo pode ser notificado sobre eventos de ciclo de vida da sessão registrando um SessionManagerListener com o SessionManager. Os callbacks SessionManagerListener definem de callback para todos os eventos de ciclo de vida da sessão.

A 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 na v2. usando métodos no Cast.CastApi.

Na v2, o Cast.Listener callbacks fornecem notificações de mudanças no estado do dispositivo, incluindo volume, estado mudo, status de espera etc.

No CAF, as notificações de mudança de estado de volume/silenciar ainda são entregues por callback no Cast.Listener. esses listeners são registrados CastSession. Todas as notificações de estado restantes do dispositivo são entregues por CastStateListener callbacks; Esses listeners são registrados no CastSession. Certifique-se de ainda cancelar o registro de listeners quando os fragmentos, atividades ou apps associados forem excluídos em segundo plano.

Lógica de reconexão

Assim como na v2, o CAF tenta restabelecer conexões de rede que forem perdidos devido à perda temporária do sinal Wi-Fi ou a outros erros de rede. Isso agora é no nível da sessão. uma sessão pode entrar em um estado "suspenso" quando for perdida e voltará para a conta "conectado" quando a conectividade for restaurada. O framework faz a reconexão Receptor da Web e reconexão de qualquer canal de transmissão como parte desse processo.

Além disso, o CAF também adiciona retomada automática de sessão, que é ativada pelo padrão (e pode ser desativado por CastOptions Se o aplicativo remetente for enviado para o segundo plano ou for encerrado (por deslizar ou devido a uma falha) enquanto uma sessão de transmissão está em andamento, o o framework tentará retomar essa sessão quando o aplicativo remetente voltar para o primeiro plano ou for reiniciado; isso é tratado automaticamente SessionManager, que emite os callbacks apropriados para todas as SessionManagerListener instâncias.

Registro de canal personalizado

Na v2, os canais personalizados (implementados usando Cast.MessageReceivedCallback) estejam registrados no Cast.CastApi. No CAF, os canais personalizados são registrados no CastSession. O registro pode ser feito SessionManagerListener.onSessionStarted método de callback. Para aplicativos de mídia, não é mais necessário registrar o canal de controle de mídia via Cast.CastApi.setMessageReceivedCallbacks; consulte a próxima seção para mais detalhes.

Controle de mídia

A classe v2 RemoteMediaPlayer foi descontinuado e não deve ser usado. No CAF, ele foi substituído pelo novo RemoteMediaClient , que oferece funcionalidade equivalente em uma API mais conveniente. É não é necessário inicializar ou registrar explicitamente esse objeto. a estrutura instancia automaticamente o objeto e registra a mídia subjacente canal no horário de início da sessão se o aplicativo receptor da Web que está sendo oferece suporte ao namespace de mídia.

O RemoteMediaClient pode ser acessado Método getRemoteMediaClient do objeto CastSession.

Na v2, todas as solicitações de mídia emitidas no RemoteMediaPlayer retornariam uma RemoteMediaPlayer.MediaChannelResult usando um callback PendingResult.

No CAF, todas as solicitações de mídia emitidas no RemoteMediaClient retornam uma RemoteMediaClient.MediaChannelResult por meio de um PendingResult que pode ser usado para acompanhar o progresso e o resultado final do solicitação.

O RemoteMediaPlayer v2 enviaria notificações sobre mudanças na mídia estado do player no receptor da Web por meio do RemoteMediaPlayer.OnStatusUpdatedListener.

No CAF, o RemoteMediaClient fornece callbacks equivalentes por meio do RemoteMediaClient.Listener interface gráfica do usuário. Qualquer número de listeners pode ser registrado com o RemoteMediaClient, que permite que vários componentes do remetente compartilhem o única instância de RemoteMediaClient associada à sessão.

Na v2, o aplicativo remetente precisava manter o usuário responsável em sincronia 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 aparecer pela primeira vez aos usuários.

Minicontrole

Na v2, é necessário implementar um minicontrole do zero no aplicativo remetente.

No CAF, o SDK fornece uma visualização personalizada, MiniControllerFragment, que você pode adicionar ao arquivo de layout do aplicativo 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 o APIs de framework do Android.

No CAF, o SDK fornece uma 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 de notificação e de 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 controle expandido do zero em app remetente.

O CAF oferece UIMediaController classe auxiliar que facilita a criação de aplicativos de controle de acesso.

O CAF adiciona um widget de controle expandido pré-criado ExpandedControllerActivity que você pode simplesmente adicionar ao seu aplicativo. Você não precisa mais 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 de codelab e apps de exemplo (link em inglês) que usam CAF.