Dopo aver presentato Chromecast e la tecnologia che Google offre per interagire con esso dalle nostre app, iniziamo ad affrontare un primo esempio che, nonostante non ci porti ancora a trasmettere contenuti alla nostra TV, sarà fondamentale per conoscere le librerie ed il codice Java di cui abbiamo bisogno per l'individuazione di tali dispositivi nella nostra LAN, nonchè per la gestione della connessione con essi.
Preparazione del progetto
Come abbiamo detto nella lezione precedente, un applicativo basato su Cast prevede due componenti: il Sender che gira nel dispositivo mobile (o anche in altri contesti) ed invia richieste e comandi al dongle, ed il Receiver che viene eseguito all'interno di Chromecast ed è realizzato con tecnologie web. Il progetto per Android Studio che vedremo in questa lezione è di tipo Sender e per funzionare ha bisogno delle seguenti dipendenze:
- Appcompat v7: è una libreria importata in quasi tutti i progetti Android, che mette a disposizione caratteristiche recenti su versioni più datate del sistema;
- Mediarouter v7: anche questa è una libreria che offre retrocompatibilità ma è specializzata su tematiche multimediali;
- Google Play Services: è la libreria che consente l'interazione di un'app con uno o più servizi Google. Offre API utili anche per la tecnologia Google Cast, tra cui le funzionalità che permetteranno di controllare le fasi salienti del flusso di comunicazione.
Per integrare queste dipendenze all'interno del progetto, si dovranno inserire le seguenti notazioni all'interno del file build.gradle relativo al nostro modulo applicativo:
dependencies {
...
...
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:mediarouter-v7:23.0.+'
compile 'com.google.android.gms:play-services:8.3.+'
}
Ovviamente, i numeri di versione potranno essere modificati in base al proprio ambiente di lavoro.
Collegarsi ad un dispositivo Chromecast
Il widget simbolo della tecnologia che stiamo trattando è il Cast Button, visibile nella figura seguente, abbastanza usato di ricente su Android in molte app (quella di YouTube in primis).
Anche noi lo useremo e sarà il comando principale per gestire le nostre connessioni a Chromecast. Lo inseriamo come un normale item di un menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item android:id="@+id/media_route_menu_item"
android:title="Chromecast"
app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
app:showAsAction="always"
/>
</menu>
Questo item sarà quindi configurato tramite il metodo onCreateOptionsMenu
all'interno dell'Activity principale:
@Override
public boolean onCreateOptionsMenu( Menu menu ) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate( R.menu.main, menu );
MenuItem mediaRouteMenuItem = menu.findItem( R.id.media_route_menu_item );
MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat.getActionProvider( mediaRouteMenuItem );
mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);
return true;
}
Non sarà necessario - a differenza delle comuni voci di menu - gestire l'evento di click, in quanto il Cast Button è un widget molto autonomo: sarà gestito da un oggetto MediaRouteActionProvider
che, per la selezione delle route (le vie di comunicazione multimediali disponibili), si appoggerà ad un MediaRouteSelector
che inizializzeremo a breve.
Il codice per Cast che scriveremo dovrà innanzitutto essere legato al ciclo di vita dell'Activity, per questo inizializzeremo nell'onCreate
i principali oggetti che ci permetteranno di interagire con il framework:
public class MainActivity extends AppCompatActivity {
private MediaRouter mMediaRouter;
private MediaRouteSelector mMediaRouteSelector;
private MediaRouter.Callback mMediaRouterCallback;
private CastDevice mSelectedDevice;
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
mMediaRouter = MediaRouter.getInstance( getApplicationContext() );
mMediaRouteSelector = new MediaRouteSelector.Builder()
.addControlCategory(CastMediaControlIntent.categoryForRemotePlayback(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID))
.build();
mMediaRouterCallback = new MediaRouterCallback();
}
/* altri metodi dell'Activity */
} // fine classe MainActivity
Il MediaRouter è la classe principale del framework in quanto controlla tutta la gestione dei flussi multimediali: ne recuperiamo un riferimento e lo conserviamo per usi futuri. Questo è anche il momento di inizializzare il MediaRouteSelector
con cui si specificheranno le caratteristiche che la route dovrà possedere. Successivamente, nei metodi onResume
e onPause
che segnano i momenti in cui l'interfaccia, rispettivamente, inizia ed interrompe l'interazione con l'utente, si utilizza il MediaRouter
per attivare/disattivare i Callback che gestiranno gli eventi legati alla scoperta di nuove route da percorrere verso Chromecast:
@Override
protected void onResume() {
super.onResume();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
}
@Override
protected void onPause() {
if ( isFinishing() ) {
mMediaRouter.removeCallback(mMediaRouterCallback);
}
super.onPause();
}
L'oggetto di Callback che abbiamo definito è molto semplice e nel nostro esempio non fa praticamente niente: userà un Toast per notificarci l'avvenuto collegamento al dispositivo che abbiamo scelto segnalandocene il nome recuperato con il metodo getFriendlyName
:
private class MediaRouterCallback extends MediaRouter.Callback {
@Override
public void onRouteSelected(MediaRouter router, RouteInfo info) {
mSelectedDevice = CastDevice.getFromBundle( info.getExtras() );
Toast.makeText(getApplicationContext(), "Collegati a "+mSelectedDevice.getFriendlyName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onRouteUnselected( MediaRouter router, RouteInfo info ) {
mSelectedDevice = null;
}
}
Le immagini seguenti indicano le operazioni che potremo svolgere con il codice che abbiamo scritto sinora:
- cliccando sul pulsante Cast appare una finestra di dialogo che ci informa dei dispositivi individuati nella rete:
Nel nostro caso ne verrà individuato uno che abbiamo denominato, in fase di configurazione, "Soggiorno";
- per chiudere la connessione con il dispositivo sarà necessario nuovamente agire sul Cast Button la cui icona, come si può vedere, appare adesso colorata internamente di bianco, a segnalare che abbiamo un collegamento in corso:
Con l'impostazione di base che questa lezione ha fornito al nostro progetto Android Studio siamo pronti ad affrontare la principale attività di Chomecast consistente nella trasmissione di contenuti multimediali. I concetti visti saranno affrontati più in profondità nei prossimi, mentre l'attività di individuazione dei dispositivi nella LAN qui messa in pratica diventerà il punto di partenza di ogni nostro esperimento.