In deze serie bouwen we een Twitter-client voor het Android-platform met behulp van de Twitter4J-bibliotheek. Deze tutorial zal zich richten op het implementeren van tweeten, retweeten en reageren op tweets. We zullen een nieuwe activiteit maken voor tweeten en antwoorden, met retweet- en antwoordknoppen geïmplementeerd voor elke tweet in de tijdlijn van de gebruiker thuis.
In de eerste vier tutorials hebben we:
Onze app krijgt naast het hoofdtijdlijnscherm een tweede activiteit. Deze nieuwe activiteit is voor het verzenden van tweets. Daarin kan de gebruiker tekst invoeren om een tweet vanuit zijn Twitter-account te verzenden. De gebruiker kan de Tweet Activity op twee manieren invoeren - door op de Tweet-knop op het hoofdscherm van de app te drukken of door binnen de tijdlijn op een antwoordknop te drukken.
Als de gebruiker op de knop Tweet drukt, krijgen deze een leeg tekstveld te zien voor het invoeren van hun tweet, met een verzendknop om door te gaan en deze te verzenden.
Als de gebruiker op de antwoordknop drukt binnen een tijdlijn-tweet, wordt deze ook weergegeven met het tekstveld, maar de gebruikersnaam voor beantwoorden is al ingevuld in het veld. Het antwoord moet ook worden verzonden met de ID van de tweet waarop wordt geantwoord en die we ook zullen implementeren.
Maak een nieuwe klasse in uw Android-project, noem het "NiceTweet" om overeen te komen met de naam die u in de eerste zelfstudie in uw Manifest-bestand hebt opgenomen. Wijzig de klassenverklaring als volgt:
public class NiceTweet breidt activiteit uit OnClickListener
U heeft de volgende Android-import nodig:
import android.app.Activity; importeer android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; importeer android.widget.Button; importeer android.widget.EditText; import android.widget.LinearLayout;
Plus deze Twitter4J importeert:
import twitter4j.StatusUpdate; import twitter4j.Twitter; importeer twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.Configuration; import twitter4j.conf.ConfigurationBuilder;
Neem de volgende instantievariabelen op in uw klassedeclaratie:
/ ** gedeelde voorkeuren voor gebruikers twitterdetails * / private SharedPreferences tweetPrefs; / ** twitter-object ** / privé Twitter tweetTwitter; / ** twitter key * / public final static static TWIT_KEY = "uw sleutel"; / ** twittergeheim * / openbare definitieve statische reeks TWIT_SECRET = "uw geheim"; / ** de update-ID voor deze tweet als deze een antwoord is * / private long tweetID = 0; / ** de gebruikersnaam voor de tweet als deze een antwoord is * / private String tweetName = "";
We gebruiken de voorkeuren, Twitter, sleutel en geheime variabelen om toegang te krijgen tot de Twitter4J-methoden voor tweeten vanuit het gebruikersaccount. Verander de sleutel en het geheim dat bij u past. De laatste twee variabelen zijn voor antwoorden. Wanneer de gebruiker binnen een tweet op de knop Reageren drukt, geven we de ID van de tweet door waarop wordt gereageerd, samen met de Twitter-schermnaam van de account waarop we reageren. We slaan deze op in de twee instantievariabelen.
Laten we de methode voor het maken van activiteiten implementeren:
/ * * onCreate called when activity is created * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); // set tweet layout setContentView (R.layout.tweet);
Het enige wat we hier doen is de tweet-lay-out instellen die we eerder in XML hebben gedefinieerd. Implementeer vervolgens de cv-methode, die wordt aangeroepen wanneer de activiteit zichtbaar wordt voor de gebruiker:
/ * * Call-instellingsmethode wanneer deze activiteit start * / @Override public void onResume () super.onResume (); // call helper methode setupTweet ();
We gaan de opgegeven hulpmethode bieden om de activiteit in te stellen voor gebruikersinteractie.
Voeg de "setupTweet" -methode als volgt aan uw klas toe:
/ ** * Methode die wordt aangeroepen wanneer deze activiteit begint * - maak je klaar om te tweeten * Sets twitter en onClick listeners * - stelt ook in voor antwoorden * / private void setupTweet () // prepare to tweet
Binnen deze methode moeten we de klas voorbereiden om gewone tweets en antwoorden te sturen. Laten we eerst de gedeelde voorkeuren gebruiken om ons Twitter-object te instantiëren:
// ontvang voorkeuren voor gebruiker twitter details tweetPrefs = getSharedPreferences ("TwitNicePrefs", 0); // krijg gebruikers-token en geheim voor authenticatie String userToken = tweetPrefs.getString ("user_token", null); String userSecret = tweetPrefs.getString ("user_secret", null); // een nieuwe twitterconfiguratie maken gebruik gebruikersdetails Configuratie twitConf = new ConfigurationBuilder () .setOAuthConsumerKey (TWIT_KEY) .setOAuthConsumerSecret (TWIT_SECRET) .setOAuthAccessToken (userToken) .setOAuthAccessTokenSecret (userSecret) .build (); // maak een twitter-instantie tweetTwitter = nieuwe TwitterFactory (twitConf) .getInstance ();
Hier maken we een Twitter-object met behulp van de authenticatie-informatie van de gebruiker samen met de ontwikkelaarssleutel en geheim voor de toepassing. Wanneer we gebruikers meenemen naar deze activiteitsklasse, geven we de ID en gebruikersnaam door als er op een tweet wordt gereageerd. We krijgen deze van de Intent:
// krijg alle gegevens die aan deze intentie zijn doorgegeven voor een antwoord. Bundle extras = getIntent (). getExtras ();
Als de tweet een gewone update is in plaats van een antwoord, zijn er geen extra's. Als er extra's zijn, weten we dat de tweet een antwoord is:
if (extras! = null) // ontvang de ID van de tweet die we beantwoorden op tweetID = extras.getLong ("tweetID"); // krijg de schermnaam van de gebruiker voor de tweet die we aan het beantwoorden zijn tweetName = extras.getString ("tweetUser"); // gebruik de doorgegeven informatie
Hier halen we de ID en de schermnaam op voor de tweet om op te antwoorden. Vervolgens gebruiken we deze informatie om de gebruikersnaam toe te voegen aan het tekstveld, nog steeds binnen de "als" -instructie:
// krijg een verwijzing naar het tekstveld voor tweeting EditText theReply = (EditText) findViewById (R.id.tweettext); // start de tweet-tekst voor het antwoord @gebruikersnaam theReply.setText ("@" + tweetName + ""); // plaats de cursor naar het einde van de tekst voor het invoeren van deReply.setSelection (theReply.getText (). length ());
We hebben de gebruikersnaam ingesteld als het eerste deel van de tweet-tekst, waarbij de cursor aan het einde wordt geplaatst, zodat de gebruiker direct zijn antwoordtekst kan typen.
Laten we vervolgens zorgen voor gevallen waarin de tweet geen antwoord is:
else EditText theReply = (EditText) findViewById (R.id.tweettext); theReply.setText ( "");
Hier stellen we eenvoudig de tekst in op een lege tekenreeks, opnieuw met behulp van de ID die we het tekstveld in de lay-out-XML hebben gegeven. Nu kunnen we de "setupTweet" -methode beëindigen door click listeners toe te voegen voor de "send" knop en de "home" knop om terug te keren naar het hoofd tijdlijn scherm:
// luisteraar instellen voor het kiezen van de startknop om naar de tijdlijn te gaan LinearLayout tweetClicker = (LinearLayout) findViewById (R.id.homebtn); tweetClicker.setOnClickListener (deze); // luisteraar instellen voor verzenden tweet-knop Knop tweetButton = (Knop) findViewById (R.id.dotweet); tweetButton.setOnClickListener (deze);
We gebruiken opnieuw de ID-waarden die we hebben opgegeven in onze lay-outbestanden.
Houd er rekening mee dat de activiteit Tweet een knop bevat om gebruikers terug te halen naar de starttijdlijn en de knop om de tweet te verzenden. Laten we nu de "onClick" -methode toevoegen om gebruikers te laten klikken op deze knoppen:
/ ** * Luistermethode voor klikken op knoppen * - voor startknop en verzendtoets voor tweet * / openbare ongeldig onClick (weergave v) // startpagina verwerken en knoppen verzenden
Krijg eerst een verwijzing naar het tekstveld:
EditText tweetTxt = (EditText) findViewById (R.id.tweettext);
Nu moeten we uitzoeken op welke knop is geklikt met schakel- en caseoverzichten:
Zoek uit op welke weergave is geklikt (v.getId ()) case R.id.dotweet: // verstuur tweet; case R.id.homebtn: // ga naar de onderbreking van de thuistijdlijn; standaard: pauze;
Voer in de case-instructie "dotweet" vóór de break-opdracht het verzenden van een tweet als volgt uit:
String toTweet = tweetTxt.getText (). ToString (); probeer // antwoordafhandeling indien (tweetName.length ()> 0) tweetTwitter.updateStatus (nieuwe StatusUpdate (toTweet) .inReplyToStatusId (tweetID)); // omgaan met normale tweets else tweetTwitter.updateStatus (toTweet); // reset de bewerkingstekst tweetTxt.setText (""); catch (TwitterException te) Log.e ("NiceTweet", te.getMessage ());
Hier controleren we of de tweet een antwoord is of niet. De "if" -instructie wordt uitgevoerd als de tweet een antwoord is, inclusief de tekst uit het tekstveld en de ID van de statusupdate waarop we reageren. De "else" -instructie zorgt voor het verzenden van gewone tweets, waarbij alleen de tekst als parameter wordt doorgegeven. De try-and-catch-blokken zijn nodig omdat we via het netwerk proberen verbinding te maken met Twitter. Na het verzenden van de tweet, al dan niet een antwoord, stellen we het tekstveld opnieuw in als leeg voor de volgende tweetupdate.
Stel voor de "homebtn" -kwestieverklaring het tekstveld in op een lege tekenreeks:
tweetTxt.setText ( "");
Eindelijk, na de switch-opdracht, maar nog steeds binnen de "onClick" -methode, de activiteit af, zodat deze terugkeert naar de home-tijdlijn:
af hebben();
Of de tweet een reactie of een gewone update is, we nemen de gebruiker onmiddellijk terug naar het hoofdscherm wanneer deze wordt verzonden, wat we ook doen wanneer ze op de startknop drukken - de afrondingsinstructie wordt in alle drie de gevallen uitgevoerd.
Om retweeten en antwoorden te implementeren, moeten we de tweet-ID en de schermnaam van de gebruiker opslaan in de retweet- en reply-knoppen voor elke tweet in de tijdlijn. Door deze gegevens op te slaan in de knop Views voor retweet en antwoorden, kunnen we detecteren welke tweet wordt geretweet of waarop wordt gereageerd wanneer de gebruiker op een knop drukt.
Omdat de informatie die we moeten opslaan bestaat uit een nummer en wat tekst, zullen we een klasse maken om het te modelleren. Maak een nieuwe klasse in uw project en noem deze "StatusData". Uw nieuwe klasse zou als volgt moeten beginnen:
public class StatusData
Voeg binnen de klasse instantievariabelen toe voor de tweet-ID en gebruikersnaam:
/ ** tweet ID * / private long tweetID; / ** gebruikersschermnaam van tweeter * / private String tweetUser;
De ID is gemodelleerd als een lange, met de schermnaam een tekststring. Voeg een constructormethode toe aan de klas:
/ ** * Constructor ontvangt ID en gebruikersnaam * @param ID * @param screenName * / public StatusData (long ID, String screenName) // instantiate variables tweetID = ID; tweetUser = Screenname;
De methode instantaliseert eenvoudigweg de twee variabelen. Voeg vervolgens een openbare methode toe zodat we de tweet-ID elders kunnen ophalen:
/ ** * Haal de ID van de tweet * @return tweetID als een lange * / openbare lange getID () return tweetID;
Voeg vervolgens een methode toe om de schermnaam terug te zetten:
/ ** * Krijg de schermnaam van de gebruiker voor de tweet * @return tweetUser als een tekenreeks * / public String getUser () return tweetUser;
Met deze methoden kunnen we deze informatie ophalen wanneer gebruikers op de retweet- of antwoordknop klikken voor een bepaalde tweet.
Nu moeten we de code uitbreiden in de adapterklasse die we hebben gemaakt ("UpdateAdapter"). In de methode "bindView" hebben we de toewijzing van gegevens aan de weergaven van de gebruikersinterface aangepast. Nu zullen we verdere verwerking toevoegen om de tweetgegevens op te nemen binnen elke retweet en antwoordknop. Voor het einde van uw "bindView" -methode, begint u als volgt:
// krijg de status-ID long statusID = cursor.getLong (cursor.getColumnIndex (BaseColumns._ID)); // krijg de gebruikersnaam String statusName = cursor.getString (cursor.getColumnIndex ("user_screen"));
Vergeet niet dat de methode "bindView" een Cursor-object is doorgegeven voor het doorlopen van de gegevens. Hier gebruiken we de Cursor om de lange ID-waarde en String-gebruikersnaam voor de huidige tweet op te halen. U hebt de volgende extra import nodig:
importeer android.provider.BaseColumns;
Nu zullen we een object van onze nieuwe StatusData-klasse instantiëren, waarbij de tweetgegevens worden doorgegeven aan de constructormethode:
// maak een StatusData-object om deze StatusData te bewaren tweetData = nieuwe StatusData (statusID, statusName);
Het object StatusData bevat alles wat nodig is om een retweet of antwoord voor de betreffende tweet te verzenden. We voegen nu een verwijzing naar dit object toe aan de retweet- en reply-knoppen voor de tweet, zodat we toegang hebben tot de informatie na klikken van de gebruiker. We gebruiken de "setTag" -methode:
// stel het statusgegevensobject in als tag voor zowel retweet- als antwoordknoppen in deze rij view.findViewById (R.id.retweet) .setTag (tweetData); row.findViewById (R.id.reply) .setTag (tweetData);
De methode "bindView" ontvangt ook een parameter die de rijweergave vertegenwoordigt waarin de tweet zal worden weergegeven. Als u terugkijkt op het updatebestand XML-lay-out, ziet u dat deze twee ID-waarden zijn opgenomen voor de knoppen. We plaatsen het label in elke knop om het StatusData-object weer te geven dat de ID en gebruikersnaam bevat voor de tweet die wordt weergegeven. Nu moeten we knopklikken instellen voor deze:
// setup onclick luisteraars voor de retweet en antwoord knoppen row.findViewById (R.id.retweet) .setOnClickListener (tweetListener); row.findViewById (R.id.reply) .setOnClickListener (tweetListener);
Hier specificeren we een kliklistener om knopklikken te verwerken. Binnen de listenermethode kunnen we de StatusData-objecten ophalen van alle geretweet en antwoordknoppen waarop is geklikt. We gaan ook toestaan dat gebruikers op de gebruikersnaam voor een tweet klikken om het gebruikersprofiel in de webbrowser te openen. Voeg hier ook een clicklistener toe aan die View:
// setup onclick voor de naam van het gebruikersscherm binnen de tweet row.findViewById (R.id.userScreen) .setOnClickListener (tweetListener);
Hierdoor kunnen we een koppeling maken met de Twitter-webinterface, zodat gebruikers toegang hebben tot functies die we niet binnen de app zelf hebben aangeboden.
Maak in de klasse UpdateAdapter een "onClickListener" om klikken af te handelen, waarbij de naam "tweetListener" wordt gebruikt die overeenkomt met wat we hebben opgegeven in de methode "bindView":
/ ** * tweetListener verwerkt clicks of reply- en retweet-knoppen * - kan ook klikken op de gebruikersnaam in een tweet * / private OnClickListener tweetListener = new OnClickListener () // onClick-methode public void onClick (View v) ;
Voeg de volgende extra invoer toe aan de klasse Adapter:
import android.view.View.OnClickListener; importeer android.content.Intent; importeer android.content.SharedPreferences; import android.widget.Toast; import android.net.Uri; import twitter4j.Twitter; importeer twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.Configuration; import twitter4j.conf.ConfigurationBuilder;
Binnen de "onClick" -methode zullen we klikken van beide knoppen plus de gebruikersnaam implementeren. Om op te merken op welke is geklikt, voegt u een switchinstructie toe:
// op welke view klik werd geklikt (v.getId ()) // antwoordknop ingedrukt case R.id.reply: // implementeer antwoordonderbreking; // knop retweet ingedrukt case R.id.retweet: // retweet pauze uitvoeren; // gebruiker heeft tweet gebruikersnaam ingedrukt case R.id.userScreen: // implementeer een bezoek aan het gebruikersprofiel; standaard: pauze;
In de antwoord-case-instructie starten we de klasse Tweet Activity, waarbij we de antwoordgegevens doorgeven, zodat de antwoord-ID en gebruikersnaam kunnen worden toegevoegd bij het verzenden van de tweet:
// maak een intentie voor het verzenden van een nieuwe tweet Intent replyIntent = new Intent (v.getContext (), NiceTweet.class); // haal de gegevens uit de tag binnen de knopweergave StatusData theData = (StatusData) v.getTag (); // geef de status ID door replyIntent.putExtra ("tweetID", theData.getID ()); // geef de gebruikersnaam replyIntent.putExtra ("tweetUser", theData.getUser ()) door; // ga naar het tweet-scherm v.getContext (). startActivity (replyIntent);
Merk op dat we de tag ophalen voor de ingedrukte weergave en deze casten als een object StatusData. Vervolgens noemen we de openbare methoden die we in de klasse StatusData hebben verstrekt om de tweet-ID en de schermnaam van de gebruiker te retourneren. We geven deze door aan de Tweet Activity als extra's en starten vervolgens de activiteit. Op dit punt wordt de gebruiker naar het Tweet-scherm geleid, waar de antwoordgegevens worden gebruikt om het beantwoorden van de juiste tweet te implementeren.
In de retweet-case-instructie, zullen we de betreffende tweet rechtstreeks retweet, met behulp van de Twitter4J-methoden. Eerste instantiëren van een Twitter-object met behulp van de gedeelde voorkeuren plus uw ontwikkelaarsleutel en geheim voor de app:
// context krijgen Context appCont = v.getContext (); // krijg voorkeuren voor gebruikerstoegang SharedPreferences tweetPrefs = appCont.getSharedPreferences ("TwitNicePrefs", 0); String userToken = tweetPrefs.getString ("user_token", null); String userSecret = tweetPrefs.getString ("user_secret", null); // nieuwe Twitter-configuratie maken Configuratie twitConf = nieuwe ConfigurationBuilder () .setOAuthConsumerKey (TWIT_KEY) .setOAuthConsumerSecret (TWIT_SECRET) .setOAuthAccessToken (userToken) .setOAuthAccessTokenSecret (userSecret) .build (); // maak een Twitter-instantie aan voor het retweeten van Twitter retweetTwitter = new TwitterFactory (twitConf) .getInstance ();
Dit is dezelfde techniek die we eerder hebben gebruikt om de Twitter-klasse te instantiëren. We kunnen het Twitter-object nu gebruiken om de retweet te verzenden. Eerst moeten we het StatusData-object ophalen van de knop waarop is geklikt:
// get tweet data van view tag StatusData tweetData = (StatusData) v.getTag ();
Nu kunnen we proberen de update te retweet in een try-blok:
probeer // retweet, geef de status-ID door uit de tag retweetTwitter.retweetStatus (tweetData.getID ()); catch (TwitterException te) Log.e (LOG_TAG, te.getMessage ());
Alle Twitter-objecten moeten een retweet verzenden is de ID van de originele tweet. Laten we de gebruiker echter bevestigen dat zijn retweet is verzonden, nog steeds binnen het try-blok:
// confirm om CharSequence text = "Retweeted!" te gebruiken; int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText (appCont, tekst, duur); toast.show ();
U kunt het bericht natuurlijk ook wijzigen als u dat wilt. Dit is hoe het eruit ziet:
Laten we nu toestaan dat de gebruiker een Twitter-profielpagina in de webbrowser bezoekt door op de schermnaam in de huidige tweet te klikken, in de case-instructie "userScreen":
// verkrijg de schermnaam van de gebruiker TextView tv = (TextView) v.findViewById (R.id.userScreen); String userScreenName = tv.getText (). ToString (); // open de profielpagina van de gebruiker in de browser Intent browserIntent = new Intent (Intent.ACTION_VIEW, Uri.parse ("http://twitter.com/" + userScreenName)); . V.getContext () startActivity (browserIntent);
Hier halen we de gebruikersnaam op als een tekststring uit de weergave zelf, die toch de schermnaam als een string weergeeft. We bouwen dit in een Twitter-profielpagina-adres, analyseren het als een URI en geven de browser de opdracht om het te openen.
Vergeet niet dat onze hoofdactiviteit van de app een knop weergeeft waarmee gebruikers rechtstreeks naar het tweetscherm kunnen worden geleid. Laten we dat nu implementeren. Voeg in uw hoofdactiviteitsklasse het volgende toe binnen uw "setupTimeline" -methode, overal nadat u de weergave van de hoofdinhoud hebt ingesteld:
// setup onclick listener voor tweet-knop LinearLayout tweetClicker = (LinearLayout) findViewById (R.id.tweetbtn); tweetClicker.setOnClickListener (deze);
De knop met de knop Tweet komt overeen met wat we hebben opgenomen in het XML-lay-outbestand van de hoofdtijdlijn. De hoofdactiviteitsklasse gaat klikken van de Tweet-knop verwerken. Als u kijkt naar uw "onClick" -methode binnen de hoofdactiviteit ("TwitNiceActivity" als u de naam in de eerste zelfstudie gebruikte), zou u een switch-instructie met één case-statement voor de knop "aanmelden" moeten zien. Voeg als volgt een tweede aanvraag voor de Tweet-knop toe (vóór de standaardverklaring):
// gebruiker heeft knop tweetknop ingedrukt R.id.tweetbtn: // start tweet-activiteit startActivity (nieuwe Intent (this, NiceTweet.class)); breken;
Hier beginnen we gewoon met de activiteit Tweet. We hoeven geen informatie door te geven aan de activiteit, omdat de gebruiker het eenvoudigweg start om een gewone tweet te verzenden.
Dat is onze Twitter-app compleet! Voer de app uit op een emulator of apparaat om deze te laten functioneren. Op de eerste run moet je natuurlijk toestemming geven om de app je Twitter-account te laten gebruiken. Je kunt optioneel een apart Twitter-account maken om de app mee te testen in plaats van je normale account te gebruiken. Na autorisatie zou je de thuis-tijdlijn moeten zien die de meest recente tweets voorstelt van de accounts die je volgt. Test tweeten, retweeten en antwoorden, en zorg ervoor dat uw tijdlijn automatisch wordt bijgewerkt op het door u gekozen interval.
In deze tutorialserie hebben we een eenvoudige Twitter-client voor Android gemaakt. Er zijn veel manieren waarop u de app kunt verbeteren en verbeteren, zoals de mogelijkheid om directe berichten te bekijken of gebruikersprofielen in de app te bekijken in plaats van de webbrowser te gebruiken. U kunt ook vermeldingen van gebruikers binnen klikbare tweets opnemen (d.w.z. koppelen van een tekstreeks voorafgegaan door "@" aan de profielpagina voor die gebruiker). Met een soortgelijk proces kunt u hashtags ondersteunen. Meer geavanceerde Twitter-clients geven ook conversaties weer bij het selecteren van een afzonderlijke tweet, waarbij de antwoorden in chronologische volgorde worden weergegeven.
Wat de applicatie-implementatie betreft, zijn er ook verbeteringen die u zou kunnen overwegen. Als de gebruiker bijvoorbeeld een lage connectiviteit heeft, kunt u het downloaden van de profielafbeeldingen implementeren als achtergrondproces. U kunt ook een vorm van image caching implementeren om de efficiëntie te maximaliseren. In plaats van dat de app automatisch de lijstweergave vernieuwt met nieuwe tweets, zou u een knop bovenaan de tijdlijn kunnen implementeren, zodat gebruikers het scherm kunnen bedienen, met de knop die aangeeft hoeveel nieuwe tweets beschikbaar zijn. Ten slotte kunt u de efficiëntie verbeteren door de service in een aparte thread te zetten.
Ik hoop dat je deze serie over het maken van een Twitter-client voor het Android-platform leuk vond! Naast het leren aansluiten van uw apps op Twitter, heeft u nu ervaring met het gebruik van een externe bibliotheek plus een aantal verschillende Android-platformbronnen, zoals databases, adapters, services en broadcasts. Dit zijn allemaal belangrijke vaardigheden waarvan uw toekomstige Android-projecten zullen profiteren. De downloadbare broncode bevat aanvullende opmerkingen die u mogelijk nuttig vindt.