Dans cette série, nous construisons un client Twitter pour la plate-forme Android à l'aide de la bibliothèque Twitter4J. Ce didacticiel créera une base de données SQLite pour stocker la chronologie de départ de l'utilisateur. Nous allons également mapper les données de la base de données aux vues que nous avons créées la dernière fois à l'aide d'un adaptateur, afin que l'utilisateur puisse voir leurs mises à jour..
Dans les deux premiers tutoriels, nous avons configuré le projet dans Eclipse, enregistré l'application avec Twitter, importé le fichier JAR Twitter4J et créé l'interface utilisateur. Nous avons également réussi à amener les utilisateurs à se connecter à leur compte Twitter et à autoriser l'application à accéder à leurs tweets..
Ce didacticiel créera une base de données SQLite pour stocker la chronologie de départ de l'utilisateur. Nous allons également mapper les données de la base de données aux vues que nous avons créées la dernière fois à l'aide d'un adaptateur, afin que l'utilisateur puisse voir leurs mises à jour..
Entrons directement et créons la base de données de montage en utilisant SQLite. Créez une nouvelle classe dans votre projet en la sélectionnant dans l'explorateur de packages, en choisissant Fichier, Nouveau puis Classe. Entrez "NiceDataHelper" comme nom de classe. Ouvrez le nouveau fichier de classe et étendez la déclaration comme suit:
Classe publique NiceDataHelper étend SQLiteOpenHelper
Il s'agit d'une classe d'assistance de base de données pour le système SQLite. Dans cette classe, nous allons créer et gérer la base de données pour les tweets de la chronologie de base.
Ajoutez les instructions d'importation suivantes en haut de la classe:
importer android.content.Context; importer android.database.sqlite.SQLiteDatabase; importer android.database.sqlite.SQLiteOpenHelper; importer android.provider.BaseColumns; importer android.util.Log;
Ces importations concernent le traitement de base de la base de données et la consignation des erreurs, ainsi que le contexte de l'application pour référence générale..
La base de données va contenir une seule table pour les mises à jour de tweet. Ce tableau comprendra les colonnes suivantes pour chaque tweet: l'ID d'état Twitter; le texte du tweet; le pseudo du tweeter; l'heure à laquelle le tweet a été envoyé; l'URL de l'image de profil du tweeter.
Commencez par créer des constantes dans la classe:
/ ** version de la base de données * / private static final int int DATABASE_VERSION = 1; / ** nom de la base de données * / private static final String DATABASE_NAME = "home.db"; / ** Colonne ID * / private static final Chaîne HOME_COL = BaseColumns._ID; / ** tweet text * / private static final Chaîne UPDATE_COL = "update_text"; / ** nom d'écran twitter * / private static final String USER_COL = "user_screen"; / ** heure tweeted * / private static final String TIME_COL = "update_time"; / ** image de profil utilisateur * / private static final String USER_IMG = "user_img";
Ces variables constantes incluent le nom de version de la base de données, que vous devez modifier si vous souhaitez mettre à niveau la base de données dans les développements futurs de votre application. Les variables incluent également le nom de la base de données et les noms des colonnes. La classe BaseColumns nous permet d'affecter une colonne d'identifiant unique en utilisant le suffixe "_id".
Prochaine construction de la table de création SQLite Chaîne pour la table de base:
/ ** chaîne de création de la base de données * / private static final String DATABASE_CREATE = "CREATE TABLE home (" + HOME_COL + "INTEGER PAS NULL, PRIMARY KEY," + UPDATE_COL + "TEXT," + USER_COL + "TEXT," + TIME_COL + "INTEGER , "+ USER_IMG +" TEXT); ";
Créez la méthode constructeur pour votre classe d'assistance de base de données:
/ ** * Méthode constructeur * @param context * / NiceDataHelper (contexte de contexte) super (contexte, DATABASE_NAME, null, DATABASE_VERSION);
Le constructeur appelle simplement la méthode superclass. Ajoutez ensuite la méthode "onCreate" dans laquelle nous allons exécuter la création de la table de base de données:
/ * * onCreate exécute la chaîne de création de base de données * / @Override public void onCreate (base de données SQLiteDatabase) db.execSQL (DATABASE_CREATE);
Ici, nous exécutons simplement la chaîne SQL de création de base de données. A la fin de la méthode, la table aura été créée.
Pour terminer la préparation de notre base de données, implémentez la méthode "onUpgrade" si vous décidez de modifier la base de données ultérieurement:
/ * * onUpgrade supprime la table home et exécute la chaîne de création * / @Override public void onUpgrade (base de données SQLiteDat, int oldVersion, int newVersion) db.execSQL ("DROP TABLE IF EXISTS home"); db.execSQL ("VACUUM"); onCreate (db);
Cela vous permet de mettre à niveau votre base de données en modifiant le numéro de version et la chaîne de création, ou l’une des colonnes..
Nous allons maintenant ajouter une méthode finale à notre classe d'assistance de base de données. Cette méthode va renvoyer des valeurs à partir des dernières mises à jour de statut récupérées sur Twitter et sera appelée à partir de la classe de service créée dans le prochain didacticiel. Ajoutez le contour de la méthode comme suit:
/ ** * getValues récupère les enregistrements de base de données * - appelés depuis TimelineUpdater dans TimelineService * - il s'agit d'une méthode statique pouvant être appelée sans instance de la classe * * @param status * @return ContentValues result * / public static ContentValues getValues ( Status status) // prépare ContentValues pour qu'il retourne ContentValues homeValues = new ContentValues (); // récupère les valeurs // renvoie les valeurs return homeValues;
Dans cette méthode, nous allons convertir l'objet Status transmis en un ensemble de ContentValues. La classe Status fait partie de la bibliothèque Twitter4J et modélise une seule mise à jour de statut ou un tweet. Lorsque le service d'application récupère la chronologie de base de l'utilisateur, il transmet chacune des mises à jour de statut à la méthode "getValues". Cette méthode récupérera les informations du tweet que nous souhaitons stocker dans la base de données, à savoir l’ID, le texte, le nom d’utilisateur, l’heure et l’URL de l’image de profil. La méthode placera chacun de ces éléments dans un ensemble de valeurs de contenu qu'il retournera ensuite. Le service essaiera ensuite d'écrire les données de ContentValues dans la base de données, en les mettant à jour avec les tweets récemment récupérés..
Nous allons implémenter la majeure partie de ce processus lors de la création du service dans le prochain didacticiel. Pour le moment, tout ce que nous devons faire est de fournir le corps de la méthode "getValues". Avant la ligne dans laquelle les valeurs sont renvoyées, ajoutez les éléments suivants:
try // récupère chaque valeur de la table 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 (Exception te) Log.e ("NiceDataHelper", te.getMessage ());
Le processus peut provoquer des exceptions, les blocs try et catch sont donc nécessaires. Notez que la méthode tente d'extraire chaque élément de la mise à jour de statut que nous avons conçu pour que la base de données soit stockée à l'aide des méthodes Twitter4J. Vous aurez besoin de deux autres importations ajoutées à la classe:
importer twitter4j.Status; importer android.content.ContentValues;
Nous allons utiliser une classe Adapter pour mapper les données du tweet sur l'interface utilisateur Vues que nous avons créées dans le dernier tutoriel. Le ListView que nous avons créé dans le fichier de mise en page XML de la timeline va afficher les nouvelles mises à jour de tweet dès qu'elles sont disponibles. Chaque mise à jour de tweet sera affichée dans la mise en page XML de mise à jour que nous avons également définie. Si vous revenez à "res / layout / update.xml", vous verrez qu'il y a des sections pour afficher tous les éléments de données que nous stockons dans la base de données, à savoir l'image de profil de l'utilisateur et le nom d'écran, le tweet et l'heure il a été tweeté.
La classe Adapter va mapper les données de tweet de mise à jour entrantes sur ces éléments d'affichage de l'interface utilisateur. Plutôt que de devoir implémenter cela manuellement, la classe "SimpleCursorAdapter" nous permet d'automatiser une partie du processus, en mappant des données à des vues tout en nous permettant de personnaliser ce processus de mappage en fonction des besoins de l'application..
Créez une nouvelle classe dans votre application, en la nommant "UpdateAdapter". Étendez la déclaration de classe comme suit:
Classe publique UpdateAdapter étend SimpleCursorAdapter
Importez la classe parent et la classe Log comme suit:
importer android.widget.SimpleCursorAdapter; importer android.util.Log;
Ajoutez des variables d'instance comme suit:
/ ** clé de développeur twitter * / public final statique String TWIT_KEY = "votre clé"; // modifier / ** secret du développeur Twitter * / public final statique String TWIT_SECRET = "votre secret"; // modifier / ** chaînes représentant la base de données noms de colonne à associer aux vues * / static final String [] from = "update_text", "user_screen", "update_time", "user_img"; / ** affiche les ID d’élément permettant de mapper les valeurs d’enregistrement de la base de données sur * / static final int [] à = R.id.updateText, R.id.userScreen, R.id.updateTime, R.id.userImg; private String LOG_TAG = "UpdateAdapter";
Modifiez les clés du développeur Twitter pour qu'il reflète le vôtre, comme vous l'avez utilisé dans la classe d'activité principale de l'application dans le dernier tutoriel. Le tableau "de" représente le nom de chaque colonne de la table de la base de données en cours de mappage. Le tableau "to" représente les ID des vues sur lesquelles les éléments "de" vont être mappés. Les ID ont tous été inclus dans les mises en page XML que nous avons créées dans le dernier tutoriel..
Dans votre classe Adapter, ajoutez une méthode constructeur comme suit:
/ ** * Le constructeur configure l'adaptateur, en passant 'de' données à 'en' vues '@param contexte * @param c * / public UpdateAdapter (contexte de contexte, curseur c) super (contexte, R.layout.update, c , de à);
Ce code appelle le constructeur de la superclasse, en passant par le contexte de l'application, l'élément View dans lequel les données vont être affichées, le curseur pour parcourir les données et les tableaux "de" et "à" que nous avons créés en tant que variables d'instance. Vous aurez besoin des instructions d'importation suivantes pour ce code:
importer android.content.Context; importer android.database.Cursor;
Ceci exécute la partie centrale du processus de mappage, c’est-à-dire l’affichage des données dans les vues spécifiées. Cependant, nous souhaitons également adapter le comportement et l'apparence des éléments d'interface utilisateur résultants. Nous allons adapter la procédure de mappage pour récupérer l'image de profil de chaque tweet et formater l'heure de mise à jour. Dans le dernier tutoriel de la série, nous étendrons également ce code afin de configurer les écouteurs qui cliquent sur le bouton retweet, le bouton de réponse et le nom d'utilisateur Twitter de chaque tweet..
Implémentez la méthode "bindView" au sein de votre classe Adapter en utilisant le plan suivant:
/ * * Lier les données aux vues visibles * / @Override public void bindView (Ligne de vue, Contexte, Curseur) super.bindView (ligne, contexte, curseur);
Ici, nous appelons simplement la méthode superclass. La méthode "bindView" nous permet de spécifier un traitement supplémentaire lorsque les données sont mappées sur les vues. Essayons d’abord de télécharger l’image de profil du tweet de la mise à jour actuelle:
try // récupère l'URL de l'image de profil profileURL = nouvelle URL (cursor.getString (cursor.getColumnIndex ("user_img"))); // définit l'image dans la vue pour le tweet en cours ImageView profPic = (ImageView) row.findViewById (R.id.userImg); profPic.setImageDrawable (Drawable.createFromStream ((InputStream) profileURL.getContent (), "")); catch (Exception te) Log.e (LOG_TAG, te.getMessage ());
Nous avons besoin des blocs try et catch car nous essayons de charger une ressource externe. La méthode obtient d'abord l'URL de l'image de profil telle qu'elle est stockée dans la colonne de la base de données. Ensuite, la méthode obtient une référence à l'élément View dans lequel afficher l'image, à l'aide de son attribut ID, comme indiqué dans le fichier de mise en forme XML mis à jour. Enfin, le code récupère l'image en tant que InputStream, l'important en tant que Drawable et le définissant en tant qu'image dans ImageView. Vous aurez besoin des importations suivantes:
importer java.io.InputStream; importer java.net.URL; importer android.graphics.drawable.Drawable; importer android.view.View; importer android.widget.ImageView;
Modifions maintenant l'affichage de l'heure de mise à jour, car elle sera stockée dans la base de données sous forme de nombre. Pour le convertir en une heure relative lisible par l'homme, ajoutez le code suivant après le bloc catch:
// récupère le temps de mise à jour long createdAt = cursor.getLong (cursor.getColumnIndex ("update_time")); // récupère la vue temporelle de la mise à jour TextView textCreatedAt = (TextView) row.findViewById (R.id.updateTime); // ajuste l'affichage de l'heure pour qu'il soit lisible par l'homme textCreatedAt.setText (DateUtils.getRelativeTimeSpanString (createdAt) + "");
Nous récupérons d’abord la valeur de la colonne sous la forme long, puis nous obtenons une référence à l’élément View pour l’afficher dans le cadre de la mise à jour XML. Enfin, nous le formatons sous forme de chaîne afin que l'utilisateur puisse voir quand le tweet a été envoyé par rapport à l'heure actuelle. Vous aurez besoin des instructions d'importation supplémentaires suivantes:
importer android.text.format.DateUtils; importer android.widget.TextView;
De retour dans la classe d'activité principale de l'application "TwitNiceActivity", implémentons maintenant la méthode "setupTimeline". Dans le prochain tutoriel, nous ajouterons le traitement du service à la méthode, mais pour le moment, gérons le démarrage de la base de données et de l'adaptateur. Avant de commencer avec la méthode, ajoutez les variables d'instance suivantes en haut de votre classe:
/ ** Vue principale de la timeline de la maison * / private ListView homeTimeline; / ** assistant de base de données pour les données de mise à jour * / private NiceDataHelper timelineHelper; / ** update database * / private SQLiteDatabase timelineDB; / ** curseur de traitement des données * / private Cursor timelineCursor; / ** adaptateur pour les données de mappage * / private UpdateAdapter timelineAdapter;
Nous allons utiliser ces variables lors de la construction de la timeline. Ajoutez ce qui suit pour spécifier la taille par défaut pour l'affichage de l'image de profil:
ProfileImage.ImageSize imageSize = ProfileImage.NORMAL;
Vous devrez ajouter les importations suivantes:
importer twitter4j.ProfileImage; importer android.database.Cursor; importer android.database.sqlite.SQLiteDatabase; importer android.widget.ListView; importer android.widget.LinearLayout;
Maintenant, pour définir la chronologie. Si vous avez créé le plan de la méthode "setupTimeline" pour le test de la dernière fois, vous pouvez simplement ajouter le corps de la méthode ensuite. Sinon, créez le plan de méthode maintenant:
/ ** * setupTimeline affiche la timeline Twitter principale de l'utilisateur * / private void setupTimeline () // corps de la méthode
Vous vous souvenez peut-être de la dernière fois que cette méthode a été appelée lorsque l'utilisateur a déjà autorisé l'application à utiliser son compte Twitter. Dans la méthode, nous allons instancier la classe Database Helper, récupérer une base de données lisible, instancier la classe Adapter et la configurer pour mapper les données à nos vues. Commencez par définir le contenu de la timeline View:
setContentView (R.layout.timeline);
Certaines des méthodes que nous allons utiliser peuvent générer des exceptions, aussi ajoutez-vous ensuite aux blocs try et catch:
try // récupère la timeline catch (Exception te) Log.e (LOG_TAG, "Impossible d'extraire la timeline:" + te.getMessage ());
Nous ajouterons les prochains extraits de code dans le bloc try. Ici nous allons instancier les variables que nous avons déclarées en haut de la classe. Commencez par obtenir une référence à ListView à partir de la disposition de la timeline, dans laquelle les vues de mise à jour apparaîtront:
// obtenir une référence à la vue liste homeTimeline = (ListView) findViewById (R.id.homeList);
Créez ensuite une instance de la classe Database Helper et utilisez-la pour récupérer une base de données lisible:
// instancie timelineHelper de l'assistant de base de données = new NiceDataHelper (this); // récupère la base de données timelineDB = timelineHelper.getReadableDatabase ();
La première ligne crée une instance de la classe Database Helper que nous avons définie, tandis que la seconde récupère la base de données. Examinons maintenant la base de données et obtenons un curseur pour la traverser, en transmettant ce curseur à la classe Adapter:
// interroge la base de données, les derniers tweets en premier timelineCursor = timelineDB.query ("home", null, null, null, null, null, null, "update_time DESC"); // gérer les mises à jour à l'aide d'un curseur startManagingCursor (timelineCursor); // instancie l'adaptateur timelineAdapter = new UpdateAdapter (this, timelineCursor);
La requête de base de données récupère simplement tout ce qui se trouve dans la table, en commençant par le classement avec les tweets de mise à jour les plus récents. Nous passons le curseur à la méthode constructeur de la classe Adapter créée.
Dans ce didacticiel, nous avons construit notre base de données de chronologie tweet, défini un adaptateur pour afficher les données dans notre interface utilisateur Vues et utilisé ces classes dans l'activité principale de notre application pour créer le scénario visible..
Dans le prochain didacticiel, nous allons configurer un récepteur de service et de diffusion afin de rechercher en permanence de nouvelles mises à jour et de les afficher dans la chronologie de départ de l'utilisateur. Au moment où vous exécutez l'application, vous ne verrez aucune mise à jour, car nous n'avons pas encore récupéré la chronologie de l'utilisateur. Dans le cadre de la classe Service, nous allons extraire la timeline à l'aide des méthodes Twitter4J, en les appelant à des intervalles définis pour extraire de manière répétée les tweets les plus récents des comptes suivis par l'utilisateur. Nous écrirons ensuite les résultats dans la base de données et les présenterons dans la chronologie..