I denne serien bygger vi en Twitter-klient for Android-plattformen ved hjelp av Twitter4J-biblioteket. Denne opplæringen vil opprette en SQLite-database for å lagre brukerens hjemme tidslinje. Vi vil også kartlegge dataene fra databasen til visningene vi opprettet sist gang ved hjelp av en adapter, slik at brukeren kan se sine oppdateringer.
I de to første opplæringen oppretter vi prosjektet i Eclipse, registrerte appen med Twitter, importerte Twitter4J JAR-filen og bygde brukergrensesnittet. Vi håndterte også å få brukerne til å logge på Twitter-kontiene og autorisere appen for å få tilgang til tweets.
Denne opplæringen vil opprette en SQLite-database for å lagre brukerens hjemme tidslinje. Vi vil også kartlegge dataene fra databasen til visningene vi opprettet sist gang ved hjelp av en adapter, slik at brukeren kan se sine oppdateringer.
La oss komme rett inn og opprette tidslinjedatabasen ved hjelp av SQLite. Opprett en ny klasse i prosjektet ditt ved å velge det i Package Explorer, velg File, New then Class. Skriv inn "NiceDataHelper" som klassenavnet. Åpne den nye klassefilen og utvide erklæringen som følger:
offentlig klasse NiceDataHelper utvider SQLiteOpenHelper
Dette er en databasehjelpeklasse for SQLite-systemet. I denne klassen vil vi opprette og administrere databasen for hjemme tidslinje tweets.
Legg til følgende importerklæringer øverst i klassen:
importer android.content.Context; importer android.database.sqlite.SQLiteDatabase; importer android.database.sqlite.SQLiteOpenHelper; importer android.provider.BaseColumns; importer android.util.Log;
Denne importen er for grunnleggende databasebehandling og feilsøking, i tillegg til søknadskonteksten for generell referanse.
Databasen skal inneholde et enkelt bord for tweet-oppdateringene. Denne tabellen vil inneholde følgende kolonner for hver tweet: Twitter status ID; tweetteksten; skjermnavnet til diskanthøyttaleren; tiden tweet ble sendt; Nettadressen til diskantens profilbilde.
Start med å lage noen konstanter i klassen:
/ ** db versjon * / privat statisk endelig int DATABASE_VERSION = 1; / ** databasens navn * / privat statisk sluttstreng DATABASE_NAME = "home.db"; / ** ID kolonne * / privat statisk sluttstreng HOME_COL = BaseColumns._ID; / ** tweet tekst * / privat statisk endelig streng UPDATE_COL = "update_text"; / ** twitter skjermnavn * / privat statisk sluttstreng USER_COL = "user_screen"; / ** tid tweeted * / privat statisk endelig streng TIME_COL = "update_time"; / ** brukerprofil bilde * / privat statisk sluttstreng USER_IMG = "user_img";
Disse konstante variablene inkluderer databaseversjonsnavnet, som du bør endre hvis du ønsker å oppgradere databasen i fremtidige utviklinger av appen din. Variablene inkluderer også navnet på databasen og navnene på kolonnene. Klassen BaseColumns hjelper oss til å tilordne en unik ID-kolonne ved hjelp av suffikset "_id".
Bygg deretter SQLite create table String for hjemmebordet:
/ ** databaseopprettingsstreng * / privat statisk sluttstreng DATABASE_CREATE = "CREATE TABLE home (" + HOME_COL + "INTEGER IKKE NULL PRIMARY KEY," + UPDATE_COL + "TEXT," + USER_COL + "TEXT", + TIME_COL + "INTEGER , "+ USER_IMG +" TEXT); ";
Opprett konstruktormetoden for din databasehjelpeklasse:
/ ** * Konstruksjonsmetode * @param kontekst * / NiceDataHelper (Kontekst kontekst) super (kontekst, DATABASE_NAME, null, DATABASE_VERSION);
Konstruktøren kaller ganske enkelt superklasse-metoden. Deretter legger du til "onCreate" -metoden der vi skal utføre opprettelsen av databasetabellen:
/ * * onCreate kjører databaseopprettelsesstreng * / @Override public void onCreate (SQLiteDatabase db) db.execSQL (DATABASE_CREATE);
Her utfører vi bare databaseoppretting av SQL String. På slutten av metoden vil tabellen være opprettet.
For å fullføre utarbeidelsen av databasen, implementer du "onUpgrade" -metoden hvis du bestemmer deg for å endre databasen på et senere tidspunkt:
/ * * onUpgrade drops hjemmebord og utfører opprettelsesstreng * / @Override public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) db.execSQL ("DROP TABLE IF EXISTS home"); db.execSQL ( "Vacuum"); onCreate (db);
Dette gjør at du kan oppgradere databasen ved å endre versjonen og opprettelsen String, eller noen av kolonnene.
Vi vil nå legge til en endelig metode til vår databasehjelpeklasse. Denne metoden kommer til å returnere verdier fra de siste hentede Twitter statusoppdateringene, og vil bli kalt fra tjenesten klassen vi lager i neste opplæring. Legg til metodebeskrivelsen som følger:
/ ** * getValues henter databasen poster * - kalt fra TimelineUpdater i TimelineService * - dette er en statisk metode som kan kalles uten en forekomst av klassen * * @param status * @return ContentValues resultat * / offentlige statiske ContentValues getValues ( Status status) // utarbeide ContentValues for å returnere ContentValues homeValues = new ContentValues (); // få verdiene // returnere verdiene returnere homeValues;
Inne i denne metoden skal vi konvertere det bestått Status-objektet til et sett med ContentValues. Status-klassen er en del av Twitter4J-biblioteket, som modellerer en enkelt statusoppdatering eller tweet. Når applikasjonstjenesten henter brukerens hjemme tidslinje, vil den passere hver av Status oppdateringene i den til "getValues" metoden. Denne metoden vil hente informasjonen fra tweetet som vi vil lagre i databasen, dvs. ID, tekst, brukernavn, tid og profil bildeadresse. Metoden vil sette hver av disse i et sett med ContentValues som den da vil returnere. Tjenesten vil da forsøke å skrive dataene i ContentValues til databasen, oppdatere den med de nylig hentede tweets.
Vi vil gjennomføre mesteparten av denne prosessen når vi oppretter Tjenesten i neste opplæring. For nå er alt vi trenger å gjøre, å gi kroppen av "getValues" -metoden. Før linjen der verdiene returneres, legg til følgende:
prøv // få hver verdi fra tabellen homeValues.put (HOME_COL, status.getId ()); homeValues.put (UPDATE_COL, status.getText ()); homeValues.put (USER_COL, status.getUser (). getScreenName ()); homeValues.put (TIME_COL, status.getCreatedAt (). getTime ()); homeValues.put (USER_IMG, status.getUser (). getProfileImageURL (). toString ()); fangst (Unntak te) Log.e ("NiceDataHelper", te.getMessage ());
Prosessen kan forårsake unntak, så prøv og fang blokkene er nødvendige. Legg merke til at metoden forsøker å hente hvert element av Statusoppdateringen som vi laget databasen for å lagre ved hjelp av Twitter4J-metodene. Du vil trenge et annet par importert til klassen:
importer twitter4j.Status; importer android.content.ContentValues;
Vi skal bruke en Adapter-klasse for å kartlegge tweet-dataene til brukergrensesnittet Visninger vi opprettet i den siste opplæringen. ListViewen vi opprettet i XML-layoutfilen for tidslinjen, skal vise de nye tweet-oppdateringene etter hvert som de blir tilgjengelige. Hver tweet-oppdatering vil bli vist i oppdaterings XML-oppsettet vi også har definert. Hvis du ser tilbake på "res / layout / update.xml" vil du se at det er seksjoner for å vise alle dataelementene vi lagrer i databasen, dvs. brukerprofilbildet og skjermnavnet, tweetet og tiden det ble tweeted.
Adapter-klassen skal kartlegge innkommende oppdaterings tweet-data til disse brukergrensesnittet Se elementer. I stedet for å måtte implementere dette manuelt, lar klassen "SimpleCursorAdapter" oss automatisere en del av prosessen, kartlegging av data til Visninger, samtidig som vi tillater oss å skreddersy denne kartleggingsprosessen slik at den passer til appens behov.
Opprett en ny klasse i appen din, og navngi den "UpdateAdapter". Utvid klassedeklarasjonen som følger:
offentlig klasse UpdateAdapter utvider SimpleCursorAdapter
Importer foreldre klassen og Log klassen som følger:
importer android.widget.SimpleCursorAdapter; importer android.util.Log;
Legg til forekomstvariabler som følger:
/ ** twitter utvikler nøkkel * / offentlig endelig statisk streng TWIT_KEY = "din nøkkel"; // alter / ** twitter utvikler hemmelig * / offentlig endelig statisk streng TWIT_SECRET = "din hemmelige"; // alter / ** strenger som representerer database kolonnenavn for å kartlegge til visninger * / statisk endelig streng [] fra = "update_text", "user_screen", "update_time", "user_img"; / ** vise element ID-er for å kartlegge databaseopptaksverdier til * / static final int [] til = R.id.updateText, R.id.userScreen, R.id.updateTime, R.id.userImg; privat streng LOG_TAG = "UpdateAdapter";
Endre Twitter-utvikleren Nøkkel og hemmelig for å reflektere din egen, som du brukte i appens hovedaktivitetsklasse i den siste opplæringen. "Fra" -arrangementet representerer navnet på hver databasetabellkolonne som er kartlagt. "Til" -arrangementet representerer IDene til visningene som "fra" -elementene skal kartlegges til. IDene ble alle inkludert i XML-oppsettene vi opprettet i den siste opplæringen.
I Adapter-klassen legger du til en konstruktormetode som følger:
/ ** * Konstruktør setter opp adapter, passerer "fra" data og "til" visninger * @param kontekst * @param c * / offentlig oppdateringsadapter (kontekst kontekst, markør c) super (kontekst, R.layout.update, c , fra til);
Denne koden kaller superklasse-konstruktøren, passerer programkonteksten, visningselementet der dataene skal vises, markøren for å krysse dataene og "fra" og "til" -arrayene vi opprettet som forekomstvariabler. Du må ha følgende importerklæringer for denne koden:
importer android.content.Context; importer android.database.Cursor;
Dette utfører den sentrale delen av kartleggingsprosessen, dvs. visning av dataene innenfor de angitte visninger. Vi vil imidlertid også skreddersy oppførselen og utseendet til de resulterende brukergrensesnittelementene. Vi vil tilpasse kartleggingsprosedyren for å hente profilbildet for hver tweet og formatere oppdateringstiden. I den siste opplæringen av serien vil vi også utvide denne koden for å sette opp lyttere for retweet-knappen, svarknappen og Twitter-brukernavnet for hvert tweet.
Implementer bindView-metoden i Adapter-klassen din ved hjelp av følgende disposisjon:
/ * * Bind dataene til synlige visninger * / @Override public void bindView (Vis rad, Kontekst kontekst, Markørmarkør) super.bindView (rad, kontekst, markør);
Her kaller vi bare superclass-metoden. Med "bindView" -metoden kan vi spesifisere ytterligere behandling for når dataene er kartlagt til visningene. La oss først prøve å laste ned profilbildet for den nåværende oppdaterings tweet:
prøv // få profil bilde URL profilURL = ny URL (cursor.getString (cursor.getColumnIndex ("user_img"))); // sett bildet i visningen for den aktuelle tweet ImageView profPic = (ImageView) row.findViewById (R.id.userImg); profPic.setImageDrawable (Drawable.createFromStream ((InputStream) profileURL.getContent (), "")); fangst (Unntak te) Log.e (LOG_TAG, te.getMessage ());
Vi trenger forsøket og fanger blokker fordi vi prøver å laste en ekstern ressurs. Metoden får først URL-adressen til profilbildet som lagret i databasekolonnen. Deretter får metoden en referanse til Vis-elementet for å vise bildet i, ved hjelp av ID-attributtet, som vi angir i oppdaterings XML-layoutfilen. Til slutt henter koden bildet som en InputStream, importerer den som en Drawable og setter den som bildet i ImageView. Du trenger følgende import:
importer java.io.InputStream; importer java.net.URL; importer android.graphics.drawable.Drawable; importer android.view.View; importer android.widget.ImageView;
La oss nå endre visning av oppdateringstiden, da den blir lagret i databasen som et tall. For å konvertere den til en menneskelig lesbar relativ tid, legg til følgende kode etter fangstblokken:
// få oppdateringstid lenge opprettetAt = cursor.getLong (cursor.getColumnIndex ("update_time")); // få oppdateringstiden se TextView textCreatedAt = (TextView) row.findViewById (R.id.updateTime); // juster måten tiden vises for å gjøre det menneskelig lesbar textCreatedAt.setText (DateUtils.getRelativeTimeSpanString (createdAt) + "");
Først henter vi kolonneverdien som en lang, så få en referanse til Vis-elementet for å vise den som en del av oppdaterings XML. Endelig formaterer vi det som en streng slik at brukeren kan se når tweetet ble sendt i forhold til nåtid. Du vil trenge følgende tilleggsangivelser:
importer android.text.format.DateUtils; importer android.widget.TextView;
Tilbake i appens hovedaktivitetsklasse "TwitNiceActivity" la oss nå implementere "setupTimeline" -metoden. I neste veiledning legger vi til Tjenestebehandlingen til metoden, men for nå lar vi håndtere oppstart av databasen og Adapteren. Før du begynner på metoden, legg til følgende instansvariabler øverst i klassen din:
/ ** hovedvisning for hjemme tidslinjen * / private ListView homeTimeline; / ** databasehjelp for oppdateringsdata * / privat NiceDataHelper tidslinjeHelper; / ** oppdater database * / privat SQLiteDatabase timelineDB; / ** markør for håndtering av data * / privat Markør tidslinje Markør; / ** adapter for kartlegging av data * / privat UpdateAdapter tidslinjeAdapter;
Vi vil bruke disse variablene når du bygger tidslinjen. Legg til følgende for å angi standardstørrelsen for profilbildevisning:
ProfileImage.ImageSize imageSize = ProfileImage.NORMAL;
Du må legge til følgende import:
importer twitter4j.ProfileImage; importer android.database.Cursor; importer android.database.sqlite.SQLiteDatabase; importer android.widget.ListView; importer android.widget.LinearLayout;
Nå for å sette tidslinjen opp. Hvis du opprettet "setupTimeline" -metoden for å teste forrige gang, kan du bare legge til metoden kroppen neste. Hvis ikke, opprett metodebeskrivelsen nå:
/ ** * setupTimeline viser brukerens hovedhjem Twitter tidslinje * / privat tomt oppsettTimeline () // metode kropp
Du kan huske fra siste gang at denne metoden kalles når brukeren allerede har autorisert appen til å bruke sin Twitter-konto. Innenfor metoden vil vi instantiere Database Helper-klassen, hente en lesbar database, instantiere Adapter-klassen og sette den til å kartlegge dataene til våre Visninger. Begynn med å angi tidslinjens innhold Vis:
setContentView (R.layout.timeline);
Noen av metodene vi skal bruke kan kaste unntak, så neste legg prøve og ta blokker:
prøv // få tidslinjen fange (Unntak te) Log.e (LOG_TAG, "Kunne ikke hente tidslinje:" + te.getMessage ());
Vi legger til de neste utdragene av kode i prøveblokken. Her skal vi instansere variablene vi erklærte oss på toppen av klassen. Først får du en referanse til ListView fra tidslinjeplanleggingen, der oppdateringsvisninger vil vises:
// få referanse til listevisningen homeTimeline = (ListView) findViewById (R.id.homeList);
Deretter oppretter du en forekomst av Database Helper-klassen og bruker den til å hente en lesbar database:
// instantiate database helper timelineHelper = new NiceDataHelper (dette); // få databasen timelineDB = timelineHelper.getReadableDatabase ();
Den første linjen her oppretter en forekomst av databasen Helper klassen vi definerte, mens den andre faktisk henter databasen. La oss nå spørre databasen og skaffe en markør for å krysse den, og passere denne markøren til Adapter-klassen:
// spørre databasen, de siste tweets første timelineCursor = timelineDB.query ("home", null, null, null, null, null, "update_time DESC"); // administrere oppdateringene ved hjelp av en cursor startManagingCursor (tidslinjemarkør); // instantiate adapter timelineAdapter = ny UpdateAdapter (dette, tidslinjemarkør);
Databasespørsmålet er bare å hente alt fra bordet, og bestiller det med de nyeste oppdaterings tweets først. Vi sender markøren til konstruktormetoden til Adapter-klassen vi opprettet.
I denne opplæringen har vi bygget vår tweet tidslinjedatabase, definert en adapter for visning av dataene i brukergrensesnittet vårt, og utnyttet disse klassene i vår apps hovedaktivitet for å bygge den synlige tidslinjen.
I den neste opplæringen vil vi sette opp en service- og kringkasting mottaker for kontinuerlig å hente nye oppdateringer og vise dem i brukerens hjem tidslinje. For øyeblikket når du kjører appen, ser du ingen oppdateringer, siden vi ikke har hentet brukerens tidslinje ennå. Som en del av Tjenesten-klassen henter vi tidslinjen ved hjelp av Twitter4J-metodene, kaller disse med bestemte intervaller for å gjenta de siste tweets fra kontoene brukeren følger. Vi vil da skrive resultatene til databasen og presentere dem i tidslinjevisningen.