Ce document détaille la conception et la mise en œuvre d'une application mobile Android destinée à aider les étudiants à suivre et à résumer leurs activités quotidiennes. Commanditée par le département de génie logiciel, cette application vise à simplifier le processus d'enregistrement et de consultation des progrès académiques et personnels, ainsi qu'à fournir des rappels personnalisés.
Objectifs du projet
Phase 1 : Fonctionnalités de base
- Enregistrement et connexion utilisateur : Les utilisateurs peuvent s'inscrire en fournissant leur identifiant d'étudiant, leur nom, leur numéro de téléphone et leur classe. L'application mémorise le nom de l'utilisateur après la première connexion pour une saisie facilitée. L'identifiant d'étudiant sert de nom d'utilisateur unique, et des options de connexion biométriques ou par code PIN de l'appareil sont envisagées pour plus de commodité.
- Journal quotidien : Permet aux utilisateurs de consigner des entrées quotidiennes comprenant la date, un mot-clé principal, un résumé détaillé, le nombre de jours consécutifs d'activité (comptage automatique) et le record de jours consécutifs.
- Rappels personnalisés : Une fonction de bloc-notes avec alarme intégrée pour configurer des rappels pour des événements ou des tâches quotidiens.
- Gestion des données : Les données de l'activité du jour en cours sont stockées localement sur l'appareil, tandis que les données historiques sont synchronisées avec un serveur distant.
Phase 2 : Statistiques et rapports avancés
- Statistiques globales : Permet aux enseignants de consulter et d'analyser les registres quotidiens de tous les étudiants.
- Recherche de journaux : Offre la possibilité de rechercher des entrées de journal par mot-clé ou par contenu du résumé.
- Génération de rapports : Capacité à générer automatiquement des rapports récapitulatifs pour tous les utilisateurs, incluant le numéro de série, la classe, l'identifiant de l'étudiant, le nom et le nombre total de contributions.
Vue d'ensemble de l'application mobile
1. Introduction à l'application de journal de bord
L'application de journal de bord Android est actuellement à sa version 1.0, compatible avec les smartphones Android. Elle offre aux utilisateurs la flexibilité d'éditer leurs entrées, de recevoir des rappels et de consulter leurs journaux à tout moment et n'importe où.
2. Système de gestion des utilisateurs
Afin de faciliter l'utilisation, un système de gestion des utilisateurs a été mis en place. Les utilisateurs doivent créer un compte en utilisant leur identifiant d'étudiant comme nom d'utilisateur. L'application est conçue pour mémoriser les identifiants de connexion, avec la possibilité d'utiliser la reconnaissance d'empreintes digitales ou le code PIN du téléphone pour un déverrouillage sécurisé.
3. Connexion et inscription
Après l'inscritpion, les utilisateurs peuvent se connecter avec leur identifiant et leur mot de passe. L'application propose une option pour enregistrer les informations de connexion, permettant une connexion automatique lors des démarrages ultérieurs. L'interface de connexion et d'inscription est simple et intuitive.
4. Fonction d'ajout d'entrée quotidienne
Chaque utilisateur peut ajouter de nouvelles entrées de journal quotidien selon ses besoins. Chaque entrée est structurée en cinq parties principales :
- La date de la'ctivité.
- Un mot-clé résumant l'activité.
- Un résumé détaillé de la journée.
- Le nombre de jours consécutifs d'activités.
- Le record personnel du plus grand nombre de jours consécutifs.
Toutes ces informations sont initialement stockées sur l'appareil mobile.
5. Fonction de consultation des entrées
Cette fonctionnalité permet aux utilisateurs de consulter les détails de toutes leurs entrées quotidiennes enregistrées, facilitant ainsi le suivi de leurs activités et de leurs progrès.
6. Fonction de rappel (alarme)
L'application intègre un système de rappel pour alerter les utilisateurs à des moments spécifiques, les encourageant à compléter leur résumé quotidien. La section suivante présente des extraits de code pour l'implémentation de la logique de la base de données, des modèles de données et des composants Android essentiels, traduits et restructurés pour une meilleure clarté.
Exemples de code : Implémentation Android
Modèles de données
Voici les classes Java représentant les structures de données pour les utilisateurs et les activités quotidiennes. Ces modèles sont utilisés pour interagir avec la base de données SQLite.
ActiviteQuotidienne.java
package com.example.suiviquotidien.modeles;
public class ActiviteQuotidienne {
private int id;
private String dateActivite;
private String motCle;
private String resumeJour;
private int joursConsecutifs;
private int maxJoursConsecutifs;
public ActiviteQuotidienne() {
}
public ActiviteQuotidienne(String dateActivite, String motCle, String resumeJour, int joursConsecutifs, int maxJoursConsecutifs) {
this.dateActivite = dateActivite;
this.motCle = motCle;
this.resumeJour = resumeJour;
this.joursConsecutifs = joursConsecutifs;
this.maxJoursConsecutifs = maxJoursConsecutifs;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getDateActivite() { return dateActivite; }
public void setDateActivite(String dateActivite) { this.dateActivite = dateActivite; }
public String getMotCle() { return motCle; }
public void setMotCle(String motCle) { this.motCle = motCle; }
public String getResumeJour() { return resumeJour; }
public void setResumeJour(String resumeJour) { this.resumeJour = resumeJour; }
public int getJoursConsecutifs() { return joursConsecutifs; }
public void setJoursConsecutifs(int joursConsecutifs) { this.joursConsecutifs = joursConsecutifs; }
public int getMaxJoursConsecutifs() { return maxJoursConsecutifs; }
public void setMaxJoursConsecutifs(int maxJoursConsecutifs) { this.maxJoursConsecutifs = maxJoursConsecutifs; }
@Override
public String toString() {
return "ActiviteQuotidienne{" +
"id=" + id +
", dateActivite='" + dateActivite + '\'' +
", motCle='" + motCle + '\'' +
", resumeJour='" + resumeJour + '\'' +
", joursConsecutifs=" + joursConsecutifs +
", maxJoursConsecutifs=" + maxJoursConsecutifs +
'}';
}
}
Utilisateur.java
package com.example.suiviquotidien.modeles;
public class Utilisateur {
private int id;
private String identifiant;
private String motDePasse;
private String nomComplet;
private String telephone;
private String classe;
public Utilisateur(String identifiant, String motDePasse, String nomComplet, String telephone, String classe) {
this.identifiant = identifiant;
this.motDePasse = motDePasse;
this.nomComplet = nomComplet;
this.telephone = telephone;
this.classe = classe;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getIdentifiant() { return identifiant; }
public void setIdentifiant(String identifiant) { this.identifiant = identifiant; }
public String getMotDePasse() { return motDePasse; }
public void setMotDePasse(String motDePasse) { this.motDePasse = motDePasse; }
public String getNomComplet() { return nomComplet; }
public void setNomComplet(String nomComplet) { this.nomComplet = nomComplet; }
public String getTelephone() { return telephone; }
public void setTelephone(String telephone) { this.telephone = telephone; }
public String getClasse() { return classe; }
public void setClasse(String classe) { this.classe = classe; }
@Override
public String toString() {
return "Utilisateur{" +
"id=" + id +
", identifiant='" + identifiant + '\'' +
", motDePasse='" + motDePasse + '\'' +
", nomComplet='" + nomComplet + '\'' +
", telephone='" + telephone + '\'' +
", classe='" + classe + '\'' +
'}';
}
}
Gestionnaire de base de données SQLite
La classe BaseDeDonneesSuiviQuotidien étend SQLiteOpenHelper et gère la création de la base de données, les mises à niveau des schémas et toutes les opérations CRUD (Création, Lecture, Mise à jour, Suppression) pour les tables utilisateurs et activites_quotidiennes.
BaseDeDonneesSuiviQuotidien.java
package com.example.suiviquotidien.bdd;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
import com.example.suiviquotidien.modeles.Utilisateur;
import com.example.suiviquotidien.modeles.ActiviteQuotidienne;
public class BaseDeDonneesSuiviQuotidien extends SQLiteOpenHelper {
private static final String NOM_BDD = "app_suivi_quotidien.db";
private static final int VERSION_BDD = 1;
// Table Utilisateur
private static final String TABLE_UTILISATEURS = "utilisateurs";
private static final String COL_USER_ID = "_id";
private static final String COL_USER_IDENTIFIANT = "identifiant";
private static final String COL_USER_MOTDEPASSE = "mot_de_passe";
private static final String COL_USER_NOM_COMPLET = "nom_complet";
private static final String COL_USER_TELEPHONE = "telephone";
private static final String COL_USER_CLASSE = "classe";
// Table ActiviteQuotidienne
private static final String TABLE_ACTIVITES = "activites_quotidiennes";
private static final String COL_ACTIVITE_ID = "_id";
private static final String COL_ACTIVITE_DATE = "date_activite";
private static final String COL_ACTIVITE_MOTCLE = "mot_cle";
private static final String COL_ACTIVITE_RESUME = "resume_jour";
private static final String COL_ACTIVITE_JOURS_CONSECUTIFS = "jours_consecutifs";
private static final String COL_ACTIVITE_MAX_CONSECUTIFS = "max_jours_consecutifs";
public BaseDeDonneesSuiviQuotidien(Context context) {
super(context, NOM_BDD, null, VERSION_BDD);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_UTILISATEURS = "CREATE TABLE " + TABLE_UTILISATEURS + "("
+ COL_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COL_USER_IDENTIFIANT + " TEXT UNIQUE NOT NULL,"
+ COL_USER_MOTDEPASSE + " TEXT NOT NULL,"
+ COL_USER_NOM_COMPLET + " TEXT,"
+ COL_USER_TELEPHONE + " TEXT,"
+ COL_USER_CLASSE + " TEXT" + ")";
db.execSQL(CREATE_TABLE_UTILISATEURS);
String CREATE_TABLE_ACTIVITES = "CREATE TABLE " + TABLE_ACTIVITES + "("
+ COL_ACTIVITE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COL_ACTIVITE_DATE + " TEXT NOT NULL,"
+ COL_ACTIVITE_MOTCLE + " TEXT NOT NULL,"
+ COL_ACTIVITE_RESUME + " TEXT,"
+ COL_ACTIVITE_JOURS_CONSECUTIFS + " INTEGER,"
+ COL_ACTIVITE_MAX_CONSECUTIFS + " INTEGER" + ")";
db.execSQL(CREATE_TABLE_ACTIVITES);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_ACTIVITES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_UTILISATEURS);
onCreate(db);
}
// --- Opérations pour les utilisateurs ---
public void enregistrerUtilisateur(Utilisateur utilisateur) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues valeurs = new ContentValues();
valeurs.put(COL_USER_IDENTIFIANT, utilisateur.getIdentifiant());
valeurs.put(COL_USER_MOTDEPASSE, utilisateur.getMotDePasse());
valeurs.put(COL_USER_NOM_COMPLET, utilisateur.getNomComplet());
valeurs.put(COL_USER_TELEPHONE, utilisateur.getTelephone());
valeurs.put(COL_USER_CLASSE, utilisateur.getClasse());
db.insert(TABLE_UTILISATEURS, null, valeurs);
db.close();
}
public boolean verifierUtilisateur(String identifiant, String motDePasse) {
SQLiteDatabase db = this.getReadableDatabase();
String[] colonnes = { COL_USER_ID };
String selection = COL_USER_IDENTIFIANT + " = ?" + " AND " + COL_USER_MOTDEPASSE + " = ?";
String[] selectionArgs = { identifiant, motDePasse };
Cursor curseur = db.query(TABLE_UTILISATEURS, colonnes, selection, selectionArgs, null, null, null);
int nombreUtilisateurs = curseur.getCount();
curseur.close();
db.close();
return nombreUtilisateurs > 0;
}
public boolean identifiantExiste(String identifiant) {
SQLiteDatabase db = this.getReadableDatabase();
String[] colonnes = { COL_USER_ID };
String selection = COL_USER_IDENTIFIANT + " = ?";
String[] selectionArgs = { identifiant };
Cursor curseur = db.query(TABLE_UTILISATEURS, colonnes, selection, selectionArgs, null, null, null);
int nombreUtilisateurs = curseur.getCount();
curseur.close();
db.close();
return nombreUtilisateurs > 0;
}
// --- Opérations pour les activités quotidiennes ---
public void insererActiviteQuotidienne(ActiviteQuotidienne activite) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues valeurs = new ContentValues();
valeurs.put(COL_ACTIVITE_DATE, activite.getDateActivite());
valeurs.put(COL_ACTIVITE_MOTCLE, activite.getMotCle());
valeurs.put(COL_ACTIVITE_RESUME, activite.getResumeJour());
valeurs.put(COL_ACTIVITE_JOURS_CONSECUTIFS, activite.getJoursConsecutifs());
valeurs.put(COL_ACTIVITE_MAX_CONSECUTIFS, activite.getMaxJoursConsecutifs());
db.insert(TABLE_ACTIVITES, null, valeurs);
db.close();
}
public List<ActiviteQuotidienne> recupererToutesLesActivites() {
List<ActiviteQuotidienne> listeActivites = new ArrayList<>();
String selectQuery = "SELECT * FROM " + TABLE_ACTIVITES + " ORDER BY " + COL_ACTIVITE_DATE + " DESC";
SQLiteDatabase db = this.getReadableDatabase();
Cursor curseur = db.rawQuery(selectQuery, null);
if (curseur.moveToFirst()) {
do {
ActiviteQuotidienne activite = new ActiviteQuotidienne(
curseur.getString(curseur.getColumnIndexOrThrow(COL_ACTIVITE_DATE)),
curseur.getString(curseur.getColumnIndexOrThrow(COL_ACTIVITE_MOTCLE)),
curseur.getString(curseur.getColumnIndexOrThrow(COL_ACTIVITE_RESUME)),
curseur.getInt(curseur.getColumnIndexOrThrow(COL_ACTIVITE_JOURS_CONSECUTIFS)),
curseur.getInt(curseur.getColumnIndexOrThrow(COL_ACTIVITE_MAX_CONSECUTIFS))
);
activite.setId(curseur.getInt(curseur.getColumnIndexOrThrow(COL_ACTIVITE_ID)));
listeActivites.add(activite);
} while (curseur.moveToNext());
}
curseur.close();
db.close();
return listeActivites;
}
public void supprimerActivite(int idActivite) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_ACTIVITES, COL_ACTIVITE_ID + " = ?", new String[]{String.valueOf(idActivite)});
db.close();
}
public void supprimerToutesLesActivites() {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_ACTIVITES, null, null);
db.close();
}
}
Adaptateur pour la liste des activités
Cet adaptateur est un exemple d'implémentation de BaseAdapter pour afficher les objets ActiviteQuotidienne dans un ListView. Il utilise le pattern ViewHolder pour optimiser les performances de défilement.
AdaptateurActivites.java
package com.example.suiviquotidien.adaptateurs;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.suiviquotidien.modeles.ActiviteQuotidienne;
import com.example.suiviquotidien.R;
import java.util.List;
public class AdaptateurActivites extends BaseAdapter {
private Context contexte;
private List<ActiviteQuotidienne> listeActivites;
private LayoutInflater inflate;
public AdaptateurActivites(Context contexte, List<ActiviteQuotidienne> liste) {
this.contexte = contexte;
this.listeActivites = liste;
this.inflate = LayoutInflater.from(contexte);
}
@Override
public int getCount() {
return listeActivites.size();
}
@Override
public Object getItem(int position) {
return listeActivites.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
static class ViewHolder {
TextView tvDate;
TextView tvMotCle;
TextView tvResume;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder supportVue;
if (convertView == null) {
convertView = inflate.inflate(R.layout.element_liste_activite, parent, false);
supportVue = new ViewHolder();
supportVue.tvDate = convertView.findViewById(R.id.tv_date_activite);
supportVue.tvMotCle = convertView.findViewById(R.id.tv_mot_cle_activite);
supportVue.tvResume = convertView.findViewById(R.id.tv_resume_activite);
convertView.setTag(supportVue);
} else {
supportVue = (ViewHolder) convertView.getTag();
}
ActiviteQuotidienne activite = listeActivites.get(position);
supportVue.tvDate.setText(activite.getDateActivite());
supportVue.tvMotCle.setText(activite.getMotCle());
supportVue.tvResume.setText(activite.getResumeJour());
return convertView;
}
public void mettreAJourDonnees(List<ActiviteQuotidienne> nouvellesDonnees) {
this.listeActivites.clear();
this.listeActivites.addAll(nouvellesDonnees);
notifyDataSetChanged();
}
}
Récepteur d'alarme
Cette classe BroadcastReceiver est déclenchée par l'AlarmManager pour afficher un message Toast lorsque l'heure de rappel est atteinte.
RecepteurAlarme.java
package com.example.suiviquotidien.recepteurs;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class RecepteurAlarme extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Rappel: N'oubliez pas d'enregistrer votre résumé quotidien !", Toast.LENGTH_LONG).show();
}
}
Activité de Connexion
L'activité ActiviteConnexion gère l'interface utilisateur et la logique pour la connexion des utilisateurs. Elle interagit avec la base de données pour vérifier les identifiants.
ActiviteConnexion.java
package com.example.suiviquotidien.activites;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.suiviquotidien.bdd.BaseDeDonneesSuiviQuotidien;
import com.example.suiviquotidien.R;
public class ActiviteConnexion extends AppCompatActivity {
private BaseDeDonneesSuiviQuotidien bddHelper;
private EditText champIdentifiant;
private EditText champMotDePasse;
private Button boutonConnexion;
private Button boutonInscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activite_connexion);
bddHelper = new BaseDeDonneesSuiviQuotidien(this);
champIdentifiant = findViewById(R.id.champ_identifiant);
champMotDePasse = findViewById(R.id.champ_mot_de_passe);
boutonConnexion = findViewById(R.id.bouton_connexion);
boutonInscription = findViewById(R.id.bouton_inscription);
boutonConnexion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String identifiant = champIdentifiant.getText().toString().trim();
String motDePasse = champMotDePasse.getText().toString().trim();
if (TextUtils.isEmpty(identifiant) || TextUtils.isEmpty(motDePasse)) {
Toast.makeText(ActiviteConnexion.this, "L'identifiant et le mot de passe ne peuvent être vides.", Toast.LENGTH_SHORT).show();
} else {
if (bddHelper.verifierUtilisateur(identifiant, motDePasse)) {
Toast.makeText(ActiviteConnexion.this, "Connexion réussie.", Toast.LENGTH_SHORT).show();
Intent intentPrincipale = new Intent(ActiviteConnexion.this, ActivitePrincipale.class);
startActivity(intentPrincipale);
finish();
} else {
Toast.makeText(ActiviteConnexion.this, "Identifiant ou mot de passe incorrect.", Toast.LENGTH_SHORT).show();
}
}
}
});
boutonInscription.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentInscription = new Intent(ActiviteConnexion.this, ActiviteInscription.class);
startActivity(intentInscription);
finish();
}
});
}
}
Activité Principale
L'ActivitePrincipale sert de point d'entrée après la connexion. Elle permet aux utilisateurs de configurer des alarmes de rappel et de naviguer vers d'autres fonctionnalités comme l'enregistrement ou la visualisation des activités.
ActivitePrincipale.java
package com.example.suiviquotidien.activites;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;
import android.widget.Button;
import java.util.Calendar;
import java.util.TimeZone;
import com.example.suiviquotidien.recepteurs.RecepteurAlarme;
import com.example.suiviquotidien.R;
public class ActivitePrincipale extends AppCompatActivity {
private EditText champHeure;
private EditText champMinute;
private RadioButton boutonRadioActiver;
private RadioButton boutonRadioDesactiver;
private Button boutonEnregistrerActivite;
private Button boutonVoirActivites;
private Button boutonRechercherActivites;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activite_principale);
champHeure = findViewById(R.id.champ_heure_alarme);
champMinute = findViewById(R.id.champ_minute_alarme);
boutonRadioActiver = findViewById(R.id.radio_activer_alarme);
boutonRadioDesactiver = findViewById(R.id.radio_desactiver_alarme);
boutonEnregistrerActivite = findViewById(R.id.bouton_enregistrer_activite_main);
boutonVoirActivites = findViewById(R.id.bouton_voir_activites_main);
boutonRechercherActivites = findViewById(R.id.bouton_rechercher_activites_main);
boutonRadioActiver.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
int heure = Integer.parseInt(champHeure.getText().toString());
int minute = Integer.parseInt(champMinute.getText().toString());
demarrerRappel(heure, minute);
} catch (NumberFormatException e) {
Toast.makeText(ActivitePrincipale.this, "Veuillez entrer une heure et une minute valides.", Toast.LENGTH_SHORT).show();
}
}
});
boutonRadioDesactiver.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arreterRappel();
}
});
boutonEnregistrerActivite.setOnClickListener(v -> {
Intent intent = new Intent(this, ActiviteEnregistrementQuotidien.class);
startActivity(intent);
});
boutonVoirActivites.setOnClickListener(v -> {
Intent intent = new Intent(this, ActiviteVisualisationActivites.class);
startActivity(intent);
});
boutonRechercherActivites.setOnClickListener(v -> {
Toast.makeText(this, "Fonctionnalité de recherche à implémenter.", Toast.LENGTH_SHORT).show();
});
}
/**
* Active une alarme de rappel à l'heure et la minute spécifiées.
* @param heure Heure de l'alarme (0-23)
* @param minute Minute de l'alarme (0-59)
*/
private void demarrerRappel(int heure, int minute){
Calendar calendrier = Calendar.getInstance();
calendrier.setTimeInMillis(System.currentTimeMillis());
calendrier.setTimeZone(TimeZone.getTimeZone("GMT+1")); // Fuseau horaire pour la France
calendrier.set(Calendar.HOUR_OF_DAY, heure);
calendrier.set(Calendar.MINUTE, minute);
calendrier.set(Calendar.SECOND, 0);
calendrier.set(Calendar.MILLISECOND, 0);
long tempsSelectionne = calendrier.getTimeInMillis();
long tempsActuel = System.currentTimeMillis();
if(tempsActuel > tempsSelectionne) {
calendrier.add(Calendar.DAY_OF_MONTH, 1);
}
Intent intentAlarme = new Intent(ActivitePrincipale.this, RecepteurAlarme.class);
PendingIntent pendingIntentAlarme = PendingIntent.getBroadcast(ActivitePrincipale.this, 0, intentAlarme, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager gestionnaireAlarmes = (AlarmManager) getSystemService(ALARM_SERVICE);
gestionnaireAlarmes.setRepeating(AlarmManager.RTC_WAKEUP, calendrier.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntentAlarme);
Toast.makeText(this, "Rappel quotidien activé pour " + String.format("%02d:%02d", heure, minute), Toast.LENGTH_SHORT).show();
}
/**
* Désactive l'alarme de rappel.
*/
private void arreterRappel(){
Intent intentAlarme = new Intent(ActivitePrincipale.this, RecepteurAlarme.class);
PendingIntent pendingIntentAlarme = PendingIntent.getBroadcast(ActivitePrincipale.this, 0, intentAlarme, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager gestionnaireAlarmes = (AlarmManager) getSystemService(ALARM_SERVICE);
gestionnaireAlarmes.cancel(pendingIntentAlarme);
Toast.makeText(this, "Rappel quotidien désactivé.", Toast.LENGTH_SHORT).show();
}
}
Activité d'Enregistrement Quotidien
L'activité ActiviteEnregistrementQuotidien fournit un formulaire pour que les utilisateurs puissent soumettre leurs résumés d'activités quotidiens, y compris la date, le mot-clé, le résumé, et les compteurs de jours consécutifs.
ActiviteEnregistrementQuotidien.java
package com.example.suiviquotidien.activites;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import com.example.suiviquotidien.bdd.BaseDeDonneesSuiviQuotidien;
import com.example.suiviquotidien.modeles.ActiviteQuotidienne;
import com.example.suiviquotidien.R;
public class ActiviteEnregistrementQuotidien extends AppCompatActivity {
private BaseDeDonneesSuiviQuotidien bddHelper;
private TextView champDate;
private EditText champMotCle;
private EditText champResume;
private EditText champJoursConsecutifs;
private EditText champMaxJoursConsecutifs;
private Button boutonEnregistrer;
private Button boutonRetour;
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activite_enregistrement_quotidien);
bddHelper = new BaseDeDonneesSuiviQuotidien(this);
champDate = findViewById(R.id.champ_date_activite);
champMotCle = findViewById(R.id.champ_mot_cle);
champResume = findViewById(R.id.champ_resume_jour);
champJoursConsecutifs = findViewById(R.id.champ_jours_consecutifs);
champMaxJoursConsecutifs = findViewById(R.id.champ_max_jours_consecutifs);
boutonEnregistrer = findViewById(R.id.bouton_enregistrer_activite);
boutonRetour = findViewById(R.id.bouton_retour_activite);
SimpleDateFormat formatteurDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String dateActuelle = formatteurDate.format(new Date());
champDate.setText(dateActuelle);
boutonEnregistrer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String date = champDate.getText().toString().trim();
String motCle = champMotCle.getText().toString().trim();
String resume = champResume.getText().toString().trim();
String joursConsecutifsStr = champJoursConsecutifs.getText().toString().trim();
String maxJoursConsecutifsStr = champMaxJoursConsecutifs.getText().toString().trim();
if (TextUtils.isEmpty(date) || TextUtils.isEmpty(motCle) || TextUtils.isEmpty(resume)) {
Toast.makeText(ActiviteEnregistrementQuotidien.this, "La date, le mot-clé et le résumé ne peuvent être vides.", Toast.LENGTH_SHORT).show();
} else {
int joursConsecutifs = 0;
try {
joursConsecutifs = Integer.parseInt(joursConsecutifsStr);
} catch (NumberFormatException e) { /* Gérer l'erreur */ }
int maxJoursConsecutifs = 0;
try {
maxJoursConsecutifs = Integer.parseInt(maxJoursConsecutifsStr);
} catch (NumberFormatException e) { /* Gérer l'erreur */ }
ActiviteQuotidienne nouvelleActivite = new ActiviteQuotidienne(date, motCle, resume, joursConsecutifs, maxJoursConsecutifs);
bddHelper.insererActiviteQuotidienne(nouvelleActivite);
Toast.makeText(ActiviteEnregistrementQuotidien.this, "Activité enregistrée avec succès.", Toast.LENGTH_SHORT).show();
Intent intentPrincipale = new Intent(ActiviteEnregistrementQuotidien.this, ActivitePrincipale.class);
startActivity(intentPrincipale);
finish();
}
}
});
boutonRetour.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentPrincipale = new Intent(ActiviteEnregistrementQuotidien.this, ActivitePrincipale.class);
startActivity(intentPrincipale);
finish();
}
});
}
}
Activité de Visualisation des Activités
Cette activité permet de visualiser toutes les activités quotidiennes enregistrées dans un ListView. Les utilisateurs peuvent également supprimer des entrées individuelles ou toutes les entrées.
ActiviteVisualisationActivites.java
package com.example.suiviquotidien.activites;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.example.suiviquotidien.bdd.BaseDeDonneesSuiviQuotidien;
import com.example.suiviquotidien.modeles.ActiviteQuotidienne;
import com.example.suiviquotidien.adaptateurs.AdaptateurActivites;
import com.example.suiviquotidien.R;
import java.util.List;
public class ActiviteVisualisationActivites extends AppCompatActivity {
private ListView listeActivitesVue;
private Button boutonSupprimerTout;
private Button boutonRetour;
private BaseDeDonneesSuiviQuotidien bddHelper;
private AdaptateurActivites adaptateurActivites;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activite_visualisation_activites);
bddHelper = new BaseDeDonneesSuiviQuotidien(this);
listeActivitesVue = findViewById(R.id.liste_activites);
boutonSupprimerTout = findViewById(R.id.bouton_supprimer_tout);
boutonRetour = findViewById(R.id.bouton_retour_visualisation);
List<ActiviteQuotidienne> toutesActivites = bddHelper.recupererToutesLesActivites();
adaptateurActivites = new AdaptateurActivites(this, toutesActivites);
listeActivitesVue.setAdapter(adaptateurActivites);
boutonSupprimerTout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bddHelper.supprimerToutesLesActivites();
rafraichirListeActivites();
Toast.makeText(ActiviteVisualisationActivites.this, "Toutes les activités ont été supprimées.", Toast.LENGTH_SHORT).show();
}
});
listeActivitesVue.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ActiviteQuotidienne activiteSelectionnee = (ActiviteQuotidienne) adaptateurActivites.getItem(position);
bddHelper.supprimerActivite(activiteSelectionnee.getId());
rafraichirListeActivites();
Toast.makeText(ActiviteVisualisationActivites.this, "Activité supprimée.", Toast.LENGTH_SHORT).show();
}
});
boutonRetour.setOnClickListener(v -> {
Intent intentPrincipale = new Intent(ActiviteVisualisationActivites.this, ActivitePrincipale.class);
startActivity(intentPrincipale);
finish();
});
}
private void rafraichirListeActivites() {
List<ActiviteQuotidienne> nouvellesActivites = bddHelper.recupererToutesLesActivites();
adaptateurActivites.mettreAJourDonnees(nouvellesActivites);
}
}
Layout XML pour l'écran de connexion
Ceci est le fichier de mise en page XML pour l'activité de connexion (activite_connexion.xml).
activite_connexion.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/img_3"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connexion ou Inscription"
android:textSize="26sp"
android:gravity="center"
android:paddingTop="16dp"
android:paddingBottom="16dp"/>
<LinearLayout
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Identifiant :"
android:layout_marginTop="30dp"
android:textSize="25sp"
android:textColor="#000000"
android:layout_weight="1"/>
<EditText
android:id="@+id/champ_identifiant"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Saisissez votre identifiant"
android:layout_marginTop="30dp"
android:textSize="20sp"
android:textColor="#2196F3"
android:layout_weight="2"
android:inputType="text"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Mot de passe :"
android:textSize="25sp"
android:layout_marginTop="30dp"
android:textColor="#000000"
android:layout_weight="1"/>
<EditText
android:id="@+id/champ_mot_de_passe"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="Saisissez votre mot de passe"
android:textSize="20sp"
android:textColor="#2196F3"
android:layout_weight="2"
android:inputType="textPassword"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="vertical">
<Button
android:id="@+id/bouton_connexion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Se connecter"
android:textAllCaps="false"
android:textColor="#FFFFFF"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginTop="30dp"
android:textSize="25sp"/>
<Button
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginTop="30dp"
android:textSize="25sp"
android:textColor="#FFFFFF"
android:textAllCaps="false"
android:text="S'inscrire"
android:id="@+id/bouton_inscription"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>