Creazione di un client Twitter per Android Tweeting, Retweeting e Replying

In questa serie stiamo costruendo un client Twitter per la piattaforma Android utilizzando la libreria Twitter4J. Questo tutorial si concentrerà sull'implementazione di tweeting, retweeting e risposta ai tweet. Creeremo una nuova attività per twittare e rispondere, con i pulsanti retweet e reply implementati per ciascun tweet nella timeline home dell'utente.


Disponibile anche in questa serie:

  1. Creazione di un client Twitter per Android: installazione e panoramica
  2. Creazione di un client Twitter per Android: creazione dell'interfaccia
  3. Creazione di un client Twitter per Android: creazione di un database cronologico
  4. Creazione di un client Twitter per Android: recupero degli aggiornamenti tramite un servizio
  5. Creazione di un client Twitter per Android: Tweeting, Retweeting e Replying

Nei primi quattro tutorial abbiamo:

  • Registrata l'app con Twitter.
  • Importata la libreria Twitter4J.
  • Gestione dell'autenticazione utente.
  • Costruito l'interfaccia utente usando le risorse XML.
  • Creato un database SQLite per memorizzare i tweet per la timeline home dell'utente.
  • Mappato i dati alle viste visibili utilizzando un adattatore.
  • Recupero periodicamente nuovi aggiornamenti utilizzando un servizio e trasmissione.

Passaggio 1: crea un'attività Tweet

La nostra app avrà una seconda attività oltre alla schermata principale della timeline. Questa nuova attività è per l'invio di tweet. Al suo interno, l'utente può inserire il testo per inviare un tweet dal proprio account Twitter. L'utente può accedere all'attività Tweet in due modi: premendo il pulsante Tweet sulla schermata principale dell'app o premendo un pulsante di risposta all'interno della sequenza temporale.


Se l'utente preme il pulsante Tweet, verrà presentato con un campo di testo vuoto per inserire il proprio tweet, con un pulsante di invio per andare avanti e inviarlo.


Se l'utente preme il pulsante di risposta all'interno di una timeline tweet, verrà anche presentato con il campo di testo, ma il nome utente di risposta sarà già compilato all'interno del campo. La risposta deve essere inviata anche utilizzando l'ID del tweet a cui viene risposto, che implementeremo anche.

Crea una nuova classe nel tuo progetto Android, chiamandola "NiceTweet" in modo che corrisponda al nome che hai incluso nel file Manifest nel primo tutorial. Modificare la dichiarazione della classe come segue:

 public class NiceTweet estende Activity implements OnClickListener 

Avrai bisogno delle seguenti importazioni Android:

 importare android.app.Activity; importare android.content.SharedPreferences; importare android.os.Bundle; import android.util.Log; importa android.view.View; import android.view.View.OnClickListener; importa android.widget.Button; importare android.widget.EditText; import android.widget.LinearLayout;

Oltre a queste importazioni Twitter4J:

 import twitter4j.StatusUpdate; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.Configuration; import twitter4j.conf.ConfigurationBuilder;

Includere le seguenti variabili di istanza all'interno della dichiarazione della classe:

 / ** preferenze condivise per i dettagli di twitter dell'utente * / private SharedPreferences tweetPrefs; / ** oggetto Twitter ** / Twitter Twitter privato; / ** twitter key * / public final static String TWIT_KEY = "la tua chiave"; / ** twitter secret * / public static static String TWIT_SECRET = "il tuo segreto"; / ** l'ID di aggiornamento per questo tweet se è una risposta * / private long tweetID = 0; / ** il nome utente per il tweet se è una risposta * / private String tweetName = "";

Utilizzeremo le preferenze, Twitter, le variabili chiave e segreta per accedere ai metodi Twitter4J per tweeting dall'account utente. Cambia la chiave e il segreto per adattarla alla tua. Le ultime due variabili sono per le risposte. Quando l'utente preme il pulsante di risposta all'interno di un tweet, passeremo l'ID del tweet a cui viene risposto, insieme al nome dello schermo di Twitter dell'account a cui stiamo rispondendo. Li memorizzeremo nelle due variabili di istanza.

Implementiamo il metodo di creazione delle attività:

 / * * onCreate chiamato quando viene creata l'attività * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); // imposta il layout di tweet setContentView (R.layout.tweet); 

Tutto ciò che facciamo qui è impostare il layout di tweet definito in XML in precedenza. Successivamente implementare il metodo di ripresa, che viene chiamato ogni volta che l'attività diventa visibile all'utente:

 / * * Metodo di impostazione della chiamata all'avvio di questa attività * / @Override public void onResume () super.onResume (); // chiama il metodo helper setupTweet (); 

Forniremo il metodo di supporto specificato per impostare l'attività per l'interazione dell'utente.


Passaggio 2: prepararsi a Tweet

Aggiungi il metodo "setupTweet" alla tua classe come segue:

 / ** * Metodo chiamato quando questa attività inizia * - si prepara a twittare * Configura twitter e ascoltatori onClick * - imposta anche per le risposte * / private void setupTweet () // prepare to tweet

All'interno di questo metodo, abbiamo bisogno di preparare la classe per inviare tweet ordinari e risposte. Per prima cosa usiamo le Preferenze condivise per istanziare il nostro oggetto Twitter:

 // ottieni le preferenze per i dettagli di twitter dell'utente tweetPrefs = getSharedPreferences ("TwitNicePrefs", 0); // get token utente e segreto per l'autenticazione String userToken = tweetPrefs.getString ("user_token", null); String userSecret = tweetPrefs.getString ("user_secret", null); // crea una nuova configurazione di twitter usign dettagli utente Configurazione twitConf = new ConfigurationBuilder () .setOAuthConsumerKey (TWIT_KEY) .setOAuthConsumerSecret (TWIT_SECRET) .setOAuthAccessToken (userToken) .setOAuthAccessTokenSecret (userSecret) .build (); // crea un'istanza Twitter tweetTwitter = new TwitterFactory (twitConf) .getInstance ();

Qui creiamo un oggetto Twitter utilizzando le informazioni di autenticazione dell'utente insieme alla chiave dello sviluppatore e al segreto dell'applicazione. Quando portiamo gli utenti a questa classe di attività, passeremo l'ID e il nome utente se viene risposto un tweet. Otteniamo questi dall'Intento:

 // ottiene tutti i dati passati a questo intento per una risposta Bundle extras = getIntent (). getExtras ();

Se il tweet è un normale aggiornamento piuttosto che una risposta, non ci saranno extra. Se ci sono degli extra, sappiamo che il tweet è una risposta:

 if (extras! = null) // ottiene l'ID del tweet che stiamo rispondendo a tweetID = extras.getLong ("tweetID"); // ottiene il nome dello schermo utente per il tweet che stiamo rispondendo a tweetName = extras.getString ("tweetUser"); // usa le informazioni passate

Qui recuperiamo l'ID e il nome dello schermo per il tweet a cui rispondere. Successivamente usiamo queste informazioni per aggiungere il nome utente al campo di testo, sempre all'interno dell'istruzione "if":

 // ottiene un riferimento al campo di testo per twittare il testo EditText theReply = (EditText) findViewById (R.id.tweettext); // avvia il testo tweet per la risposta @username theReply.setText ("@" + tweetName + ""); // imposta il cursore alla fine del testo per la voce theReply.setSelection (theReply.getText (). length ());

Impostiamo il nome utente come prima parte del testo tweet, posizionando il cursore alla fine in modo che l'utente possa digitare il testo di risposta immediatamente.


Quindi prendiamoci cura dei casi in cui il tweet non è una risposta:

 else EditText theReply = (EditText) findViewById (R.id.tweettext); theReply.setText ( ""); 

Qui semplicemente impostiamo il testo su una stringa vuota, sempre usando l'ID che abbiamo fornito al campo di testo nell'XML del layout. Ora possiamo completare il metodo "setupTweet" aggiungendo listener di clic per il pulsante "invia" e il pulsante "home" per tornare alla schermata principale della timeline:

 // imposta listener per la scelta del pulsante home per andare alla timeline LinearLayout tweetClicker = (LinearLayout) findViewById (R.id.homebtn); tweetClicker.setOnClickListener (questo); // imposta listener per inviare il pulsante tweet Pulsante tweetButton = (Button) findViewById (R.id.dotweet); tweetButton.setOnClickListener (questo);

Usiamo nuovamente i valori ID specificati nei nostri file di layout.


Passaggio 3: Rileva clic

Ricorda che l'attività Tweet contiene un pulsante per riportare gli utenti alla timeline home e il pulsante per inviare il tweet. Ora aggiungiamo il metodo "onClick" per gestire gli utenti facendo clic su questi pulsanti:

 / ** * Metodo listener per clic sul pulsante * - per pulsante home e pulsante invia tweet * / public void onClick (Visualizza v) // gestisci home e invia clic del pulsante

Per prima cosa prendi un riferimento al campo di testo:

 EditText tweetTxt = (EditText) findViewById (R.id.tweettext);

Ora abbiamo bisogno di capire quale pulsante è stato cliccato usando le istruzioni switch e case:

 // scopri quale vista è stata cliccata switch (v.getId ()) case R.id.dotweet: // invia tweet break; case R.id.homebtn: // vai alla pausa della timeline home; default: break; 

All'interno della dichiarazione di caso "dotweet", prima dell'istruzione break, implementare l'invio di un tweet come segue:

 String toTweet = tweetTxt.getText (). ToString (); prova // gestire le risposte if (tweetName.length ()> 0) tweetTwitter.updateStatus (new StatusUpdate (toTweet) .inReplyToStatusId (tweetID)); // gestisce tweet normali else tweetTwitter.updateStatus (toTweet); // ripristina il testo di modifica tweetTxt.setText ("");  catch (TwitterException te) Log.e ("NiceTweet", te.getMessage ()); 

Qui controlliamo se il tweet è una risposta o meno. L'istruzione "if" viene eseguita se il tweet è una risposta, compreso il testo dal campo di testo e l'ID dell'aggiornamento di stato a cui stiamo rispondendo. L'istruzione "else" si occupa dell'invio di tweet ordinari, in cui solo il testo viene passato come parametro. I blocchi try and catch sono necessari poiché stiamo tentando di connetterci a Twitter attraverso la rete. Dopo aver inviato il tweet, che si tratti di una risposta o meno, riportiamo il campo di testo a vuoto in preparazione del prossimo aggiornamento dei tweet.

Per l'istruzione case "homebtn", imposta semplicemente il campo di testo su una stringa vuota:

 tweetTxt.setText ( "");

Infine, dopo l'istruzione switch ma ancora all'interno del metodo "onClick", completa l'attività in modo che ritorni alla timeline home:

 finire();

Sia che il tweet sia una risposta o un aggiornamento ordinario, riportiamo immediatamente l'utente alla schermata principale quando viene inviato, cosa che facciamo anche quando premono il pulsante home - l'istruzione di finitura verrà eseguita in tutti e tre i casi.


Passaggio 4: modello di dati Tweet per Retweet e risposte

Per implementare il retweeting e il replying, è necessario memorizzare l'ID tweet e lo screen name dell'utente all'interno dei pulsanti retweet e reply per ciascun tweet nella timeline. Memorizzando questi dati all'interno del pulsante Views per retweet e reply, saremo in grado di rilevare quale tweet è stato ritwittato o risposto quando l'utente preme un pulsante.

Poiché le informazioni che dobbiamo memorizzare comprendono un numero e un testo, creeremo una classe per modellarla. Crea una nuova classe nel tuo progetto e chiamala "StatusData". La tua nuova classe dovrebbe iniziare come segue:

 public class StatusData 

All'interno della classe, aggiungi variabili di istanza per l'ID tweet e il nome utente:

 / ** ID tweet * / tweetID privato lungo; / ** nome della schermata utente di tweeter * / private String tweetUser;

L'ID è modellato come un lungo, con lo screen-name una stringa di testo. Aggiungi un metodo di costruzione alla classe:

 / ** * Il costruttore riceve ID e nome utente * @param ID * @param screenName * / public StatusData (long ID, String screenName) // istanzia le variabili tweetID = ID; tweetUser = screenname; 

Il metodo crea semplicemente un'istanza delle due variabili. Quindi aggiungi un metodo pubblico in modo da poter recuperare l'ID tweet altrove:

 / ** * Ottieni l'ID del tweet * @return tweetID come long * / public long getID () return tweetID;

Quindi aggiungi un metodo per restituire lo screen-name:

 / ** * Ottieni il nome dello schermo utente per il tweet * @return tweetUser come String * / public String getUser () return tweetUser;

Questi metodi ci permetteranno di recuperare queste informazioni quando gli utenti fanno clic sul pulsante retweet o reply per un particolare tweet.


Passaggio 5: estendere il binding per i Retweet e le risposte

Ora dobbiamo estendere il codice nella classe Adapter che abbiamo creato ("UpdateAdapter"). Nel metodo "bindView", abbiamo adattato la mappatura dei dati all'interfaccia utente Viste. Ora aggiungeremo ulteriori elaborazioni per includere i dati dei tweet all'interno di ciascun pulsante di retweet e di risposta. Prima della fine del tuo metodo "bindView", inizia come segue:

 // ottiene lo stato ID long statusID = cursor.getLong (cursor.getColumnIndex (BaseColumns._ID)); // ottiene il nome utente String statusName = cursor.getString (cursor.getColumnIndex ("user_screen"));

Ricorda che il metodo "bindView" è passato a un oggetto Cursore per attraversare i dati. Qui usiamo il cursore per recuperare il valore ID lungo e il nome utente String per il tweet corrente. Avrai bisogno della seguente importazione aggiuntiva:

 importare android.provider.BaseColumns;

Ora istanziamo un oggetto della nostra nuova classe StatusData, passando i dati tweet al metodo del costruttore:

 // crea un oggetto StatusData per memorizzare questi StatusData tweetData = new StatusData (statusID, statusName);

L'oggetto StatusData contiene tutto il necessario per inviare un retweet o una risposta per il tweet in questione. Ora assegneremo un riferimento a questo oggetto all'interno dei pulsanti retweet e reply per il tweet, in modo che possiamo accedere alle informazioni in seguito ai clic dell'utente. Usiamo il metodo "setTag":

 // imposta l'oggetto dati di stato come tag per entrambi i pulsanti retweet e reply in questa vista row.findViewById (R.id.retweet) .setTag (tweetData); row.findViewById (R.id.reply) .setTag (tweetData);

Il metodo "bindView" riceve anche un parametro che rappresenta la riga View in cui il tweet sta per essere visualizzato. Se si guarda indietro al file di layout XML di aggiornamento, si vedrà che questi due valori ID sono inclusi per i pulsanti. Impostiamo il tag in ciascun pulsante per riflettere l'oggetto StatusData che contiene l'ID e il nome utente per il tweet visualizzato. Ora dobbiamo impostare i clic sui pulsanti per questi:

 // imposta onclick listener per i pulsanti retweet e reply row.findViewById (R.id.retweet) .setOnClickListener (tweetListener); row.findViewById (R.id.reply) .setOnClickListener (tweetListener);

Qui specifichiamo un listener di clic per gestire i clic sui pulsanti. All'interno del metodo listener, saremo in grado di recuperare gli oggetti StatusData di qualsiasi tasto retweet e reply cliccato. Inoltre, consentiremo agli utenti di fare clic sul nome utente per un tweet per poter aprire il profilo utente nel browser Web. Aggiungi anche un listener di clic a questa vista:

 // imposta onclick per il nome della schermata utente all'interno di tweet row.findViewById (R.id.userScreen) .setOnClickListener (tweetListener);

Questo ci consentirà di collegarci all'interfaccia web di Twitter in modo che gli utenti possano accedere a funzioni che non sono state fornite all'interno dell'app stessa.


Passaggio 6: Gestisci i clic sul pulsante e sul nome utente

Nella classe UpdateAdapter, crea un "onClickListener" per gestire i clic, utilizzando il nome "tweetListener" per far corrispondere ciò che abbiamo specificato nel metodo "bindView":

 / ** * tweetListener gestisce i clic di risposta e i pulsanti di retweet * - gestisce anche il clic sul nome utente all'interno di un tweet * / privato OnClickListener tweetListener = new OnClickListener () // metodo onClick public void onClick (View v) ;

Aggiungere le seguenti importazioni aggiuntive alla classe Adapter:

 import android.view.View.OnClickListener; import android.content.Intent; importare android.content.SharedPreferences; importare android.widget.Toast; import android.net.Uri; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.Configuration; import twitter4j.conf.ConfigurationBuilder;

All'interno del metodo "onClick" implementeremo i clic di entrambi i pulsanti più il nome utente. Per scoprire quale è stato cliccato, aggiungi un'istruzione switch:

 // quale vista è stata cliccata switch (v.getId ()) // pulsante di risposta premuto caso R.id.reply: // implementa reply break; // tasto retweet premuto caso R.id.retweet: // implementa retweet break; // utente ha premuto tweet nome utente case R.id.userScreen: // implementare l'interruzione del profilo utente in visita; default: break; 

All'interno dell'istruzione caso risposta, iniziamo la classe Attività Tweet, passando i dati di risposta in modo che l'ID di risposta e il nome utente possano essere inclusi quando si invia il tweet:

 // crea un intento per inviare un nuovo tweet Intent replyIntent = new Intent (v.getContext (), NiceTweet.class); // recupera i dati dal tag all'interno della visualizzazione dei pulsanti StatusData theData = (StatusData) v.getTag (); // passa l'ID di stato replyIntent.putExtra ("tweetID", theData.getID ()); // passare il nome utente replyIntent.putExtra ("tweetUser", theData.getUser ()); // vai alla schermata tweet v.getContext (). startActivity (replyIntent);

Si noti che recuperiamo il tag per la Vista premuta, gettandola come oggetto StatusData. Chiamiamo quindi i metodi pubblici che abbiamo fornito all'interno della classe StatusData per restituire l'ID tweet e lo screen name dell'utente. Li trasferiamo all'attività Tweet come extra, quindi avviiamo l'attività. A questo punto, l'utente verrà indirizzato alla schermata Tweet in cui verranno utilizzati i dati di risposta per implementare la risposta al tweet corretto.


Nella dichiarazione del caso retweet, retwetteremo direttamente il tweet in questione, utilizzando i metodi Twitter4J. Prima istanzia un oggetto Twitter utilizzando le preferenze condivise più la chiave e il segreto dello sviluppatore per l'app:

 // get context Contesto appCont = v.getContext (); // ottieni le preferenze per l'accesso utente SharedPreferences tweetPrefs = appCont.getSharedPreferences ("TwitNicePrefs", 0); String userToken = tweetPrefs.getString ("user_token", null); String userSecret = tweetPrefs.getString ("user_secret", null); // crea una nuova configurazione di Twitter Configurazione twitConf = new ConfigurationBuilder () .setOAuthConsumerKey (TWIT_KEY) .setOAuthConsumerSecret (TWIT_SECRET) .setOAuthAccessToken (userToken) .setOAuthAccessTokenSecret (userSecret) .build (); // crea istanze di Twitter per retwittare su Twitter retweetTwitter = new TwitterFactory (twitConf) .getInstance ();

Questa è la stessa tecnica che abbiamo usato per istanziare la classe di Twitter prima. Ora possiamo usare l'oggetto Twitter per inviare il retweet. Per prima cosa dobbiamo recuperare l'oggetto StatusData dal pulsante su cui è stato fatto clic:

 // ottiene tweet dati dal tag view StatusData tweetData = (StatusData) v.getTag ();

Ora possiamo provare a ritwittare l'aggiornamento in un blocco try:

 prova // retweet, passando l'ID di stato dal tag retweetTwitter.retweetStatus (tweetData.getID ());  catch (TwitterException te) Log.e (LOG_TAG, te.getMessage ());

Tutto l'oggetto Twitter deve inviare un retweet è l'ID del tweet originale. Tuttavia, diamo conferma all'utente che il suo retweet è stato inviato, sempre all'interno del blocco try:

 // conferma di usare CharSequence text = "Retweeted!"; int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText (appCont, testo, durata); toast.show ();

Ovviamente puoi modificare il messaggio, se lo desideri. Questo è quello che sembra:


Ora permettiamo all'utente di visitare una pagina del profilo Twitter nel browser Web facendo clic sul nome della schermata all'interno del tweet corrente, all'interno della dichiarazione case "userScreen":

 // ottiene il nome dello schermo utente TextView tv = (TextView) v.findViewById (R.id.userScreen); String userScreenName = tv.getText (). ToString (); // apre la pagina del profilo dell'utente nel browser Intent browserIntent = new Intent (Intent.ACTION_VIEW, Uri.parse ("http://twitter.com/" + userScreenName)); . V.getContext () startActivity (browserIntent);

Qui recuperiamo il nome utente come stringa di testo dalla vista stessa, che visualizza comunque lo screen-name come una stringa. Lo creiamo in un indirizzo di pagina del profilo di Twitter, analizzandolo come un URI e istruendo il browser per aprirlo.


Passaggio 7: implementare lo spostamento da casa a Tweet

Ricorda che la nostra app principale Attività mostra un pulsante per portare gli utenti direttamente alla schermata Tweet. Implementiamolo adesso. Nella tua classe di attività principale, aggiungi quanto segue all'interno del tuo metodo "setupTimeline", ovunque dopo aver impostato la visualizzazione del contenuto principale:

 // setup onclick listener per il pulsante tweet LinearLayout tweetClicker = (LinearLayout) findViewById (R.id.tweetbtn); tweetClicker.setOnClickListener (questo);

L'ID del pulsante Tweet corrisponde a ciò che abbiamo incluso nel file di layout XML della timeline principale. La principale classe di attività gestirà i clic del pulsante Tweet. Se osservi il tuo metodo "onClick" all'interno dell'attività principale ("TwitNiceActivity" se hai usato il nome nel primo tutorial), dovresti vedere un'istruzione switch con un'istruzione case per il pulsante "sign-on". Aggiungi una seconda dichiarazione caso per il pulsante Tweet come segue (prima dell'istruzione predefinita):

 // utente ha premuto il tasto tweet case R.id.tweetbtn: // avvia l'attività tweet startActivity (new Intent (this, NiceTweet.class)); rompere;

Qui semplicemente iniziamo l'attività Tweet. Non è necessario passare alcuna informazione all'Attività in quanto in questo caso l'utente lo sta semplicemente lanciando per inviare un normale tweet.


Questo è tutto!

Questa è la nostra app di Twitter completa! Esegui l'app su un emulatore o dispositivo per vederla funzionare. Alla prima esecuzione dovrai ovviamente consentire all'app di utilizzare il tuo account Twitter. Puoi facoltativamente creare un account Twitter separato per testare l'app, piuttosto che usare il tuo normale account. Dopo l'autorizzazione, ti verrà presentata la sequenza temporale della casa che rappresenta i tweet più recenti dagli account che segui. Prova tweeting, retweeting e replying, oltre ad assicurarti che la tua timeline si aggiorni automaticamente all'intervallo scelto.


Argomenti avanzati

In questa serie di tutorial abbiamo creato un client Twitter di base per Android. Esistono molti modi in cui è possibile migliorare e migliorare l'app, ad esempio la possibilità di visualizzare i messaggi diretti o di visualizzare i profili utente all'interno dell'app anziché dover utilizzare il browser Web. Potresti anche fare menzioni di utenti all'interno di tweets cliccabili (ovvero collegare qualsiasi stringa di testo preceduta da "@" alla pagina del profilo per quell'utente). Un processo simile ti permetterebbe di supportare gli hashtag. I client Twitter più avanzati mostrano anche le conversazioni quando selezionano un singolo tweet, mostrando le risposte in ordine cronologico.

In termini di implementazione dell'applicazione, ci sono anche miglioramenti che potresti prendere in considerazione. Ad esempio, nel caso in cui l'utente abbia una bassa connettività, è possibile implementare il download delle immagini del profilo come processo in background. Potresti anche implementare una qualche forma di memorizzazione nella cache delle immagini per massimizzare l'efficienza. Piuttosto che l'app che aggiorna automaticamente ListView con i nuovi Tweet, è possibile implementare un pulsante nella parte superiore della timeline, affinché gli utenti possano controllare il display, con il pulsante che indica quanti nuovi tweet sono disponibili. Infine, è possibile migliorare l'efficienza eseguendo il servizio in un thread separato.


Grazie per aver letto

Spero ti sia piaciuta questa serie sulla creazione di un client Twitter per la piattaforma Android! Oltre a imparare come connettere le tue app a Twitter, ora hai esperienza di utilizzo di una libreria esterna più una varietà di risorse della piattaforma Android come database, adattatori, servizi e trasmissioni. Queste sono tutte le competenze chiave di cui trarranno vantaggio i tuoi futuri progetti Android. Il codice sorgente scaricabile contiene note aggiuntive che potresti trovare utili.