In deze serie bouwen we een Twitter-client voor het Android-platform met behulp van de Twitter4J-bibliotheek. In deze zelfstudie wordt een SQLite-database gemaakt om de starttijdlijn van de gebruiker op te slaan. We zullen de gegevens uit de database ook toewijzen aan de weergaven die we de vorige keer hebben gemaakt met behulp van een adapter, zodat de gebruiker zijn updates kan zien.
In de eerste twee tutorials hebben we het project opgezet in Eclipse, de app geregistreerd met Twitter, het Twitter4J JAR-bestand geïmporteerd en de gebruikersinterface gebouwd. We hebben ook afgehandeld dat gebruikers zich moesten aanmelden bij hun Twitter-accounts en de app toestemming zouden geven om toegang te krijgen tot hun tweets.
In deze zelfstudie wordt een SQLite-database gemaakt om de starttijdlijn van de gebruiker op te slaan. We zullen de gegevens uit de database ook toewijzen aan de weergaven die we de vorige keer hebben gemaakt met behulp van een adapter, zodat de gebruiker zijn updates kan zien.
Laten we meteen beginnen en de tijdlijndatabase maken met behulp van SQLite. Maak een nieuwe klasse in uw project door deze te selecteren in de Package Explorer, kies Bestand, Nieuw en vervolgens Klasse. Voer "NiceDataHelper" in als de klassenaam. Open het nieuwe klassenbestand en verleng de verklaring als volgt:
public class NiceDataHelper breidt SQLiteOpenHelper uit
Dit is een databasehelperklasse voor het SQLite-systeem. In deze klasse zullen we de database maken en beheren voor de thuistijdlijn tweets.
Voeg de volgende importstatements toe aan de bovenkant van de klas:
importeer android.content.Context; importeer android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; importeer android.provider.BaseColumns; import android.util.Log;
Deze importen zijn voor de elementaire databaseverwerking en foutregistratie, plus de toepassingscontext voor algemene referentie.
De database zal een enkele tabel bevatten voor de tweet-updates. Deze tabel bevat de volgende kolommen voor elke tweet: de Twitter-status-ID; de tweet-tekst; de schermnaam van de tweeter; de tijd dat de tweet werd verzonden; de URL van de profielafbeelding van de tweeter.
Begin met het maken van enkele constanten in de klas:
/ ** db-versie * / private static final int DATABASE_VERSION = 1; / ** databasenaam * / private static final String DATABASE_NAME = "home.db"; / ** ID-kolom * / persoonlijke statische finale String HOME_COL = BaseColumns._ID; / ** tweet text * / private static final String UPDATE_COL = "update_text"; / ** twitter scherm naam * / private static final String USER_COL = "user_screen"; / ** time tweeted * / private static final String TIME_COL = "update_time"; / ** afbeelding van gebruikersprofiel * / statische privéafsluiting String USER_IMG = "user_img";
Deze constante variabelen bevatten de naam van de databaseversie, die u moet wijzigen als u de database wilt upgraden bij toekomstige ontwikkelingen van uw app. De variabelen bevatten ook de naam van de database en namen voor de kolommen. De klasse BaseColumns helpt ons een unieke ID-kolom toe te wijzen met het achtervoegsel "_id".
Bouw vervolgens de SQLite create table voor de hometabel:
/ ** tekenreeks voor het maken van databases * / private static final String DATABASE_CREATE = "MAAK TABLE home (" + HOME_COL + "INTEGER NOT NULL PRIMARY KEY," + UPDATE_COL + "TEXT," + USER_COL + "TEXT," + TIME_COL + "INTEGER , "+ USER_IMG +" TEXT); ";
Maak de constructormethode voor uw databasehelperklasse:
/ ** * Constructormethode * @param-context * / NiceDataHelper (contextcontext) super (context, DATABASE_NAME, null, DATABASE_VERSION);
De constructor roept gewoon de superklassemethode aan. Voeg vervolgens de "onCreate" -methode toe, waarin we het aanmaken van de databasetabel zullen uitvoeren:
/ * * onCreate voert tekenreeks voor het maken van databases * / @Override public void onCreate (SQLiteDatabase db) db.execSQL (DATABASE_CREATE);
Hier voeren we eenvoudig de SQL-string voor het maken van de database uit. Aan het einde van de methode is de tabel gemaakt.
Om de voorbereiding van onze database af te ronden, implementeert u de "onUpgrade" -methode voor het geval u beslist om de database op een later tijdstip te wijzigen:
/ * * onUpgrade verwijdert de starttabel en voert de tekenreeks creation * / @Override public void onUpgrade uit (SQLiteDatabase db, int oldVersion, int newVersion) db.execSQL ("DROP TABLE INDIEN BESTAAT"); db.execSQL ( "vacuüm"); onCreate (db);
Hiermee kunt u uw database upgraden door het versienummer en de aanmaakreeks of een van de kolommen te wijzigen.
We zullen nu een laatste methode toevoegen aan onze databasehelperklasse. Deze methode gaat waarden retourneren van de meest recent opgehaalde Twitter-statusupdates en wordt aangeroepen vanuit de serviceklasse die we in de volgende zelfstudie maken. Voeg de methode-omtrek als volgt toe:
/ ** * getValues haalt de databaserecords op * - aangeroepen vanuit TimelineUpdater in TimelineService * - dit is een statische methode die kan worden aangeroepen zonder een instantie van de klasse * * @param-status * @return ContentValues-resultaat * / public static ContentValues getValues ( Status status) // prepare ContentValues om ContentValues terug te geven homeValues = nieuwe ContentValues (); // haal de waarden op // return the values return homeValues;
Binnen deze methode gaan we het doorgegeven Status-object omzetten in een set ContentValues. De statusklasse maakt deel uit van de Twitter4J-bibliotheek en modelleert een enkele statusupdate of tweet. Wanneer de toepassingsservice de starttijdlijn van de gebruiker ophaalt, worden alle statusupdates daarin doorgegeven aan de methode "getValues". Deze methode haalt de informatie op uit de tweet die we in de database willen opslaan, dat wil zeggen de ID, tekst, gebruikersnaam, tijd en profielfoto-URL. De methode zet elk van deze in een reeks ContentValues die het dan zal teruggeven. De Service probeert dan de gegevens in de ContentValues naar de database te schrijven en bij te werken met de nieuw opgehaalde tweets.
We zullen het grootste deel van dit proces implementeren wanneer we de Service in de volgende zelfstudie maken. Voor nu alles wat we moeten doen is het lichaam van de "getValues" -methode leveren. Voeg het volgende toe vóór de regel waarin de waarden worden geretourneerd:
probeer // haal elke waarde uit de tabel 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 ()); catch (uitzondering te) Log.e ("NiceDataHelper", te.getMessage ());
Het proces kan uitzonderingen veroorzaken, dus de try en catch-blokken zijn noodzakelijk. Merk op dat de methode probeert elk element van de Status-update op te halen dat we hebben ontworpen om de database op te slaan met behulp van de Twitter4J-methoden. Je hebt nog een aantal invoer nodig die aan de klas is toegevoegd:
import twitter4j.Status; import android.content.ContentValues;
We gaan een adapterklasse gebruiken om de tweetgegevens toe te wijzen aan de gebruikersinterfaceweergaven die we in de laatste zelfstudie hebben gemaakt. De ListView die we hebben gemaakt in het XML-lay-outbestand van de tijdlijn, zal de nieuwe tweet-updates tonen zodra deze beschikbaar komen. Elke tweet-update wordt weergegeven in de updatelay-out die we ook hebben gedefinieerd. Als u terugkijkt op "res / layout / update.xml" ziet u dat er secties zijn voor weergave van alle gegevensitems die we in de database opslaan, dat wil zeggen de afbeelding van het gebruikersprofiel en de schermnaam, de tweet en de tijd het werd getweet.
Met de klasse Adapter worden inkomende update-tweetgegevens toegewezen aan deze gebruikersinterface View-items. In plaats van dit handmatig te moeten implementeren, kunnen we met de klasse "SimpleCursorAdapter" een deel van het proces automatiseren en gegevens toewijzen aan Views, terwijl we toch dit toewijzingsproces kunnen afstemmen op de behoeften van de app.
Maak een nieuwe klasse in uw app en noem deze "UpdateAdapter". Verleng de klassenverklaring als volgt:
publieke klasse UpdateAdapter breidt SimpleCursorAdapter uit
Importeer de bovenliggende klasse en Log-klasse als volgt:
import android.widget.SimpleCursorAdapter; import android.util.Log;
Voeg instantievariabelen als volgt toe:
/ ** twitter developer key * / public final static string TWIT_KEY = "uw sleutel"; // alter / ** twitter developer secret * / public final static static TWIT_SECRET = "uw geheim"; // alter / ** tekenreeksen die gegevensbestand vertegenwoordigen kolomnamen om te mappen naar views * / static final String [] van = "update_text", "user_screen", "update_time", "user_img"; / ** bekijk item-ID's voor het toewijzen van databaserecordwaarden aan * / static final int [] tot = R.id.updateText, R.id.userScreen, R.id.updateTime, R.id.userImg; private String LOG_TAG = "UpdateAdapter";
Wijzig de sleutel en het geheim van de Twitter-ontwikkelaar zodat deze overeenkomen met de uwe, zoals u in de laatste activiteit van de app hebt gebruikt in de belangrijkste activiteitsklasse van de app. De "from" -array vertegenwoordigt de naam van elke databasetabelkolom die wordt toegewezen. De "to" -array vertegenwoordigt de ID's van de weergaven waar de "van" -items naartoe worden toegewezen. De ID's zijn allemaal opgenomen in de XML-lay-outs die we in de laatste zelfstudie hebben gemaakt.
Voeg in uw adapterklasse als volgt een constructormethode toe:
/ ** * constructor stelt adapter in, geeft 'van' gegevens en 'naar' aanzichten * @param context * @param c * / public UpdateAdapter (Context-context, Cursor c) super (context, R.layout.update, c , van naar);
Deze code roept de constructor van de superklasse aan, geeft de toepassingscontext, het item Weergave waarin de gegevens zullen worden weergegeven, de cursor voor het doorlopen van de gegevens en de "van" en "naar" arrays die we als instantievariabelen hebben gemaakt. U hebt de volgende importinstructies voor deze code nodig:
importeer android.content.Context; import android.database.Cursor;
Dit voert het centrale deel van het mappingproces uit, d.w.z. het weergeven van de data binnen de gespecificeerde views. We willen echter ook het gedrag en uiterlijk aanpassen van de resulterende elementen van de gebruikersinterface. We zullen de toewijzingsprocedure aanpassen om de profielafbeelding voor elke tweet op te halen en om de update-tijd te formatteren. In de laatste zelfstudie van de serie zullen we deze code ook uitbreiden om klik-listeners in te stellen voor de retweet-knop, de antwoordknop en de Twitter-gebruikersnaam voor elke tweet.
Implementeer de methode "bindView" binnen uw adapterklasse met behulp van de volgende omtrek:
/ * * Bind de gegevens aan de zichtbare views * / @Override public void bindView (bekijk rij, context context, cursor cursor) super.bindView (rij, context, cursor);
Hier noemen we gewoon de superklasmethode. Met de methode "bindView" kunnen we aanvullende verwerking opgeven voor wanneer de gegevens worden toegewezen aan de weergaven. Laten we eerst de profielafbeelding voor de huidige updatetweet proberen te downloaden:
probeer // ontvang profielfoto URL profielURL = nieuwe URL (cursor.getString (cursor.getColumnIndex ("user_img"))); // zet de afbeelding in de weergave voor de huidige tweet ImageView profPic = (ImageView) row.findViewById (R.id.userImg); profPic.setImageDrawable (Drawable.createFromStream ((InputStream) profileURL.getContent (), "")); catch (uitzondering te) Log.e (LOG_TAG, te.getMessage ());
We hebben de blokken try en catch nodig omdat we proberen een externe bron te laden. De methode krijgt eerst de URL van de profielafbeelding zoals opgeslagen in de databasekolom. Vervolgens krijgt de methode een verwijzing naar het item Weergave om de afbeelding weer te geven, met behulp van het kenmerk ID ervan, zoals we instellen in het updatelay-outbestand. Ten slotte haalt de code de afbeelding op als een InputStream, importeert deze als een Drawable en stelt deze in als de afbeelding binnen de ImageView. U heeft de volgende invoer nodig:
import java.io.InputStream; importeer java.net.URL; importeer android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageView;
Laten we nu de weergave van de update-tijd aanpassen, omdat deze als een nummer in de database wordt opgeslagen. Om het om te zetten in een voor mensen leesbare relatieve tijd, voeg je de volgende code toe na het blok catch:
// haal de update-tijd die lang is aangemaaktAt = cursor.getLong (cursor.getColumnIndex ("update_time")); // haal de update-tijdweergave TextView textCreatedAt = (TextView) row.findViewById (R.id.updateTime); // pas de manier aan waarop de tijd wordt weergegeven om het door mensen leesbare tekst te makenCreatedAt.setText (DateUtils.getRelativeTimeSpanString (createdAt) + "");
Eerst halen we de kolomwaarde als een lange weg op en krijgen vervolgens een verwijzing naar het item Weergave om het weer te geven als onderdeel van de update-XML. Ten slotte formatteren we het als een tekenreeks, zodat de gebruiker kan zien wanneer de tweet ten opzichte van de huidige tijd is verzonden. U hebt de volgende aanvullende importinstructies nodig:
importeer android.text.format.DateUtils; import android.widget.TextView;
Terug in de hoofdactiviteitsklasse "TwitNiceActivity" van de app laten we nu de "setupTimeline" -methode implementeren. In de volgende tutorial voegen we de Service-verwerking toe aan de methode, maar laten we nu de database en adapter opstarten. Voordat u begint met de methode, voegt u de volgende instantievariabelen toe aan de bovenkant van uw klas:
/ ** hoofdweergave voor de starttijdlijn * / privé Lijstweergave homeTimeline; / ** databasehulp voor updategegevens * / private NiceDataHelper tijdlijnHelper; / ** update database * / private SQLiteDatabase timelineDB; / ** cursor voor het verwerken van gegevens * / private Cursor timelineCursor; / ** adapter voor kaartgegevens * / private UpdateAdapter timelineAdapter;
We zullen deze variabelen gebruiken bij het bouwen van de tijdlijn. Voeg het volgende toe om de standaardgrootte voor de weergave van profielafbeeldingen op te geven:
ProfileImage.ImageSize imageSize = ProfileImage.NORMAL;
U moet de volgende imports toevoegen:
import twitter4j.ProfileImage; import android.database.Cursor; importeer android.database.sqlite.SQLiteDatabase; importeer android.widget.ListView; import android.widget.LinearLayout;
Nu om de tijdlijn in te stellen. Als u de schets van de "setupTimeline" -methode hebt gemaakt om deze de laatste keer te testen, kunt u eenvoudig de volgende methode toevoegen. Als dat niet het geval is, maakt u nu de methode-schets:
/ ** * setupTimeline geeft de hoofdthuis Twitter timeline * / private void setupTimeline () // methode body van de gebruiker weer
Misschien herinnert u zich van de laatste keer dat deze methode wordt aangeroepen wanneer de gebruiker de app al heeft gemachtigd om hun Twitter-account te gebruiken. Binnen de methode zullen we de Database Helper-klasse instantiëren, een leesbare database ophalen, de adapterklasse instantiëren en deze instellen om de gegevens aan onze views toe te wijzen. Begin met het instellen van de tijdlijninhoud View:
setContentView (R.layout.timeline);
Sommige van de methoden die we gaan gebruiken kunnen uitzonderingen maken, dus voeg volgende keer proberen toe en vang blokken:
probeer // haal de tijdlijn op vangst (uitzondering te) Log.e (LOG_TAG, "Kan tijdlijn niet ophalen:" + te.getMessage ());
We zullen de volgende uittreksels van code toevoegen in het try-blok. Hier gaan we de variabelen instantiëren die we bovenaan in de klas hebben verklaard. Krijg eerst een verwijzing naar de ListView vanuit de tijdlijnlayout, waarin de update-weergaven verschijnen:
// verwijs naar de lijstweergave homeTimeline = (ListView) findViewById (R.id.homeList);
Maak vervolgens een instantie van de klasse Database Helper en gebruik deze om een leesbare database op te halen:
// instantiate database helper tijdlijnHelper = new NiceDataHelper (this); // haal de database tijdlijn opDB = tijdlijnHelper.getReadableDatabase ();
De eerste regel maakt hier een exemplaar van de klasse Database Helper die we hebben gedefinieerd, terwijl de tweede regel feitelijk de database ophaalt. Laten we nu de database opvragen en een Cursor aanschaffen om deze te doorlopen, waarbij deze Cursor wordt doorgegeven aan de adapterklasse:
// query in de database, meest recente tweets eerst timelineCursor = timelineDB.query ("home", null, null, null, null, null, "update_time DESC"); // beheer de updates met behulp van een cursor startManagingCursor (tijdlijnCursor); // instantiate adapter timelineAdapter = new UpdateAdapter (this, timelineCursor);
De databasequery haalt eenvoudig alles uit de tabel en bestelt het met de meest recente update tweets eerst. We geven de Cursor door aan de constructormethode van de adapterklasse die we hebben gemaakt.
In deze tutorial hebben we onze tweet-tijdlijndatabase gebouwd, een adapter gedefinieerd voor het weergeven van de gegevens in onze gebruikersinterfaceweergaven en deze klassen gebruikt in de hoofdactiviteit van onze app, voor het bouwen van de zichtbare tijdlijn.
In de volgende zelfstudie zullen we een service- en omroepontvanger instellen om voortdurend nieuwe updates op te halen en weer te geven in de eigen tijdlijn van de gebruiker. Op het moment dat u de app uitvoert, ziet u geen updates, omdat we de tijdlijn van de gebruiker nog niet hebben opgehaald. Als onderdeel van de serviceklasse zullen we de tijdlijn ophalen met behulp van de Twitter4J-methoden, deze met vaste intervallen oproepen om herhaaldelijk de meest recente tweets op te halen uit de accounts die de gebruiker volgt. We zullen de resultaten dan naar de database schrijven en ze presenteren in de tijdlijnweergave.