diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6cbe56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7ac24c7 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..22f7257 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..3b31283 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..ba7052b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2f1199c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..7f4f5ee --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion '27.0.3' + defaultConfig { + applicationId "com.assistanceinformatiquetoulouse.chronos24hlemans" + minSdkVersion 19 + targetSdkVersion 23 + versionCode 1 + versionName '0.7.2' + archivesBaseName = "AIT-Chronos24hLeMans-$versionName" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + productFlavors { + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + compile files('libs/FileDialog-0.2.jar') + compile 'com.android.support:appcompat-v7:23.4.0' + compile 'com.android.support:design:24.0.0' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + testCompile 'junit:junit:4.12' +} diff --git a/app/libs/FileDialog-0.2.jar b/app/libs/FileDialog-0.2.jar new file mode 100644 index 0000000..97ecb01 Binary files /dev/null and b/app/libs/FileDialog-0.2.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f572d19 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\pascal\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ApplicationTest.java b/app/src/androidTest/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ApplicationTest.java new file mode 100644 index 0000000..cc73d92 --- /dev/null +++ b/app/src/androidTest/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c8159d9 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_roller-web.png b/app/src/main/ic_roller-web.png new file mode 100644 index 0000000..ac6c501 Binary files /dev/null and b/app/src/main/ic_roller-web.png differ diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/BouttonTemporise.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/BouttonTemporise.java new file mode 100644 index 0000000..4ebd8a0 --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/BouttonTemporise.java @@ -0,0 +1,30 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Context; +import android.os.CountDownTimer; +import android.widget.Button; + +// Class BoutonTemporise +public class BouttonTemporise extends Button { + // Classe privée + private class A extends CountDownTimer { + // Constructeur + public A (long startTime, long interval) { + super(startTime, interval); + } + // Méthode onTick + // Ne rien faire + @Override + public void onTick(long millisUntilFinished) { } + + // Méthode onFinish + // Autoriser de nouveau le bouton + @Override + public void onFinish() { + BouttonTemporise.this.setEnabled(true); + } + } + public BouttonTemporise(Context context) { + super(context); + } +} diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Chronos24hLeMansActivity.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Chronos24hLeMansActivity.java new file mode 100644 index 0000000..b0d7d82 --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Chronos24hLeMansActivity.java @@ -0,0 +1,285 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.app.AlertDialog; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; +import android.support.design.widget.TabLayout; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.WindowManager; +import android.widget.Toast; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +// Class Chronos24hLeMansActivity +public class Chronos24hLeMansActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener { + // Attributs privés + private static final int REQUEST_CODE = 10; + private String pFichier; + private static Context pContext; + private TabLayout pTabLayout; + private ViewPager pViewPager; + private Toolbar pToolbar; + private ResultatSQLiteOpenHelper pResultatSQLiteOpenHelper; + private static SQLiteDatabase pSQLiteDatabase; + // Attributs publics + public static String pAbsoluteInternalPath; + public static String pAbsoluteExternalPath; + public static Vibreur aVibreur; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + pFichier = null; + pContext = getApplicationContext(); + setContentView(R.layout.activity_chronos24h_le_mans); + // Bloquer l'application en mode portrait + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + // Bloquer l'extinction automatique de l'écran + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + pAbsoluteInternalPath = this.getFilesDir().getAbsolutePath(); + pAbsoluteExternalPath = this.getExternalFilesDir(null).getAbsolutePath(); + aVibreur = new Vibreur(); + pResultatSQLiteOpenHelper = new ResultatSQLiteOpenHelper(this); + pSQLiteDatabase = pResultatSQLiteOpenHelper.getWritableDatabase(); + pResultatSQLiteOpenHelper.onCreate(pSQLiteDatabase); + //Adding toolbar to the activity + pToolbar = (Toolbar) findViewById(R.id.toolbar); + pToolbar.showOverflowMenu(); + setSupportActionBar(pToolbar); + //Initializing the tablayout + pTabLayout = (TabLayout) findViewById(R.id.tabLayout); + // Ajout des 3 onglets + pTabLayout.addTab(pTabLayout.newTab().setText("EQUIPE")); + pTabLayout.addTab(pTabLayout.newTab().setText("COURSE")); + pTabLayout.addTab(pTabLayout.newTab().setText("RESULTATS")); + pTabLayout.setTabGravity(TabLayout.GRAVITY_FILL); + //Initializing viewPager + pViewPager = (ViewPager) findViewById(R.id.pager); + //Creating our pager adapter + Pager adapter = new Pager(getSupportFragmentManager(), pTabLayout.getTabCount()); + //Adding adapter to pager + pViewPager.setAdapter(adapter); + pViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(pTabLayout)); + //Adding onTabSelectedListener to swipe views + pTabLayout.setOnTabSelectedListener(this); +// TODO : les lignes suivantes ne fonctionnent pas (suppression des barres haute et basse) + /*getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar + | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar + // remove the following flag for version < API 19 + | View.SYSTEM_UI_FLAG_IMMERSIVE);*/ + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.items, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + super.onOptionsItemSelected(item); + switch(item.getItemId()) { + case R.id.about : + AlertDialog.Builder lAlertDialog = new AlertDialog.Builder(this); + lAlertDialog.setTitle("Chronos24hLeMans\nVersion " + this.getString(R.string.version)); + lAlertDialog.setMessage("Gestion des temps pour les coureurs des 24h du Mans rollers\n© AIT 2017 (pascalh)\n\nassistanceinformatiquetoulouse@gmail.com"); + lAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + }}); + lAlertDialog.setIcon(R.drawable.ic_roller); + lAlertDialog.create().show(); + break; + case R.id.parametres : + Intent lIntent = new Intent(this, ParametresActivity.class); + lIntent.putExtra("vibreur_actif_in", aVibreur.lireEtatActif()); + lIntent.putExtra("vibreur_retard_in", aVibreur.lireRetard()); + lIntent.putExtra("vibreur_duree_in", aVibreur.lireDuree()); + startActivityForResult(lIntent, REQUEST_CODE); + break; + case R.id.effacer : + // Effacer le contenu de la database qui cootient les résultats + new AlertDialog.Builder(this) + .setTitle("Confirmation") + .setMessage("Suppression database ?") + .setPositiveButton("OUI", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + pSQLiteDatabase.execSQL("DROP TABLE RESULTAT;"); + pResultatSQLiteOpenHelper.onCreate(pSQLiteDatabase); + Toast.makeText(pContext, "Database effacée", Toast.LENGTH_LONG).show(); + } + }) + .setNegativeButton("NON", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + } + }).show(); + break; + case R.id.exporter : + // Dumper la database des résultats dans un fichier CSV + pFichier = exporterDatabaseDansCSV(TabEquipe.pEquipe.lireNomEquipe()); + if (pFichier != null) { + new AlertDialog.Builder(this) + .setTitle("Exportation") + .setMessage(String.format("Le fichier suivant a été crée :\n%s", pFichier)) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { } + }).show(); + // Rend selectable le 2ème menu (R.id.envoyer) + pToolbar.getMenu().getItem(2).setEnabled(true); + } + else { + } + break; + case R.id.envoyer : + // Envoyer le dump de la database des résultats par courriel (adresse dans strings.xml/courriel + if (pFichier != null) { + final String lCourriel = this.getString(R.string.courriel); + new AlertDialog.Builder(this) + .setTitle("Courriel") + .setMessage("Envoyer le fichier exporté par courriel sur " + lCourriel) + .setPositiveButton("OUI", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + Intent lIntent = new Intent(Intent.ACTION_SENDTO); + lIntent.setType("text/plain"); + lIntent.setData(Uri.parse("mailto:"+ lCourriel)); + lIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { lCourriel }); + lIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("Résultats équipe %s", TabEquipe.pEquipe.lireNomEquipe())); + lIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + pFichier)); + try { + startActivity(Intent.createChooser(lIntent, "Choisir le client de courriel")); + } + catch(android.content.ActivityNotFoundException e) { + } + } + }) + .setNegativeButton("NON", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { } + }).show(); + item.setEnabled(false); + } + else { + } + break; + case R.id.quitter : + // Sortir de l'application + this.finish(); + break; + default : ; + } + return (true); + } + + @Override + public void onTabSelected(TabLayout.Tab tab) { + pViewPager.setCurrentItem(tab.getPosition()); + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) { } + + @Override + public void onTabReselected(TabLayout.Tab tab) { } + + // Méthode insererDatabase + public static void insererDatabase(ContentValues contentValues) { + pSQLiteDatabase.insert("RESULTAT", null, contentValues); + } + + // Méthode exporterDatabaseDansCSV + private static String exporterDatabaseDansCSV(String nom) { + Cursor lCursor; + try { + int lNbLigne; + int lNbColonne; + lCursor = pSQLiteDatabase.rawQuery("select * from RESULTAT", null); + File lFile = new File(pAbsoluteExternalPath + File.separator + nom + ".csv"); + FileWriter lFileWriter = new FileWriter(lFile); + + BufferedWriter lBufferedWriter = new BufferedWriter(lFileWriter); + lNbLigne = lCursor.getCount(); + lNbColonne = lCursor.getColumnCount(); + if (lNbLigne > 0) { + lCursor.moveToFirst(); + for (int i = 0; i < lNbColonne; i++) { + if (i != (lNbColonne - 1)) { + lBufferedWriter.write(lCursor.getColumnName(i) + ","); + } + else { + lBufferedWriter.write(lCursor.getColumnName(i)); + } + } + lBufferedWriter.newLine(); + for (int i = 0; i < lNbLigne; i++) { + lCursor.moveToPosition(i); + for (int j = 0; j < lNbColonne; j++) { + if (j != (lNbColonne - 1)) { + lBufferedWriter.write(lCursor.getString(j) + ","); + } + else { + lBufferedWriter.write(lCursor.getString(j)); + } + } + lBufferedWriter.newLine(); + } + lBufferedWriter.flush(); + lBufferedWriter.close(); + } + else { + } + return (lFile.getAbsolutePath()); + } catch (IOException e) { + Toast.makeText(pContext, String.format("Erreur en écrivant le fichier %s", pAbsoluteExternalPath + File.separator + "resultats.csv"), Toast.LENGTH_LONG).show(); + return (null); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + //super.onActivityResult(requestCode, resultCode, data); + if ((requestCode == REQUEST_CODE) && (resultCode == RESULT_OK)) { + if (intent.hasExtra("vibreur_actif_out")) { + Boolean lActif = intent.getBooleanExtra("vibreur_actif_out", true); + aVibreur.ecrireEtatActif(lActif); + } + else { + } + if (intent.hasExtra("vibreur_retard_out")) { + long lRetard = intent.getLongExtra("vibreur_retard_out", (long)66); + aVibreur.ecrireRetard(lRetard); + } + else { + } + if (intent.hasExtra("vibreur_duree_out")) { + long lDuree = intent.getLongExtra("vibreur_duree_out", (long)20); + aVibreur.ecrireRetard(lDuree); + } + else { + } + } + else { + } + } + + @Override + public void onBackPressed() { + // Ne rien faire (désactivation du bouton retour) + // super.onBackPressed(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/CoureurAdapter.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/CoureurAdapter.java new file mode 100644 index 0000000..828904e --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/CoureurAdapter.java @@ -0,0 +1,61 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; +import java.util.ArrayList; + +// Class CoureurAdapter +public class CoureurAdapter extends ArrayAdapter { + // Atributs privés + private Context pContext; + private int pLayoutResourceId; + private int pTextViewResourceId; + private ArrayList pListeCoureurs; + private LayoutInflater pInflater; + + // Constructeur + public CoureurAdapter(Context context, int resource, int textViewResourceId, ArrayList listeCoureurs) { + super(context, resource, textViewResourceId, listeCoureurs); + this.pContext = context; + this.pLayoutResourceId = resource; + this.pTextViewResourceId = textViewResourceId; + this.pListeCoureurs = listeCoureurs; + this.pInflater = LayoutInflater.from(pContext); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View lView = convertView; + if (lView == null) { + lView = pInflater.inflate(pLayoutResourceId, parent, false); + } + else { + } + if ((pListeCoureurs != null) && (position < pListeCoureurs.size())) { + TextView lTextView = (TextView) lView.findViewById(pTextViewResourceId); + lTextView.setText(pListeCoureurs.get(position)); + } + else { + } + return(lView); + } + + @Override + public int getCount() { + return(pListeCoureurs.size()); + } + + @Override + public String getItem(int position) { + return (pListeCoureurs.get(position)); + } + + @Override + public long getItemId(int position) { + return (position); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Equipe.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Equipe.java new file mode 100644 index 0000000..1cb4865 --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Equipe.java @@ -0,0 +1,296 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; +import java.util.ArrayList; +import java.io.*; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +// Class Equipe +public class Equipe { + // Atributs privés + private boolean pLireXML; + private int pNbCoureurMax; // Nombre maximum de coureurs + private Context pContext; // Context pour lire et ecrire le fichier XML + private String pNomEquipe; // Nom de l'équipe + private ArrayList pListeCoureurs; // Liste des coureurs + private ArrayList pListeCoureursActifs; // Liste des coureurs actifs + private ArrayList pListeEtatsCoureurs; // Liste des états coureurs (true => actif, false => inactif) + + // Méthode lireXMLEquipe + // Retourne une chaine contenant le texte du fichier XML si le fichier a pu être lu, null sinon + private String lireXMLEquipe() { + byte[] lBytes; + String lString; + File lFile; + FileInputStream lFileInputStream; + try { + //lFile = new File(pContext.getFilesDir().getAbsolutePath(), "equipe.xml"); + lFile = new File(Chronos24hLeMansActivity.pAbsoluteInternalPath, "equipe.xml"); + lFileInputStream = new FileInputStream(lFile); + lBytes = new byte[(int) lFile.length()]; + lFileInputStream.read(lBytes); + lFileInputStream.close(); + lString = ""; + for (byte b : lBytes) { + lString += String.format("%c", b); + } + Log.i("", "Fichier XML lu"); + return (lString); + } + catch(IOException e) { + Log.i("", "Erreur en lisant le fichier XML"); + return (null); + } + } + + // Méthode ecrireChaine + // Ecrit une chaine de caractères dans un fichier + private void ecrireChaine(FileOutputStream fileOutputStream, String chaine) throws IOException { + fileOutputStream.write(chaine.getBytes()); + } + + // Méthode ecrireXMLEquipe + // Retourne true si le fichier a pu être écrit, false sinon + private boolean ecrireXMLEquipe() { + int i; + FileOutputStream lFileOutputStream; + try { + //lFileOutputStream = new FileOutputStream(pContext.getFilesDir().getAbsolutePath() + File.separator + "equipe.xml"); + lFileOutputStream = new FileOutputStream(Chronos24hLeMansActivity.pAbsoluteInternalPath + File.separator + "equipe.xml"); + ecrireChaine(lFileOutputStream, ""); + ecrireChaine(lFileOutputStream, String.format("", pNomEquipe, pListeCoureurs.size())); + for (i = 0; i < pListeCoureurs.size(); i++) { + if (pListeEtatsCoureurs.get(i)) { + ecrireChaine(lFileOutputStream, String.format(" " + pListeCoureurs.get(i) + "")); + } + else { + ecrireChaine(lFileOutputStream, String.format(" " + pListeCoureurs.get(i) + "")); + } + } + ecrireChaine(lFileOutputStream, ""); + lFileOutputStream.close(); + Log.i("", "Fichier XML écrit"); + return (true); + } + catch(IOException e) { + Toast.makeText(pContext, "Impossible d'écrire le fichier XML", Toast.LENGTH_SHORT).show(); + Log.i("", "Impossible d'écrire le fichier XML"); + return (false); + } + } + + // Méthode ParserXML + private void ParserXML(String chaine) { + boolean lActif = true; + String lTagName; + String lText = ""; + try { + XmlPullParserFactory lFactory = XmlPullParserFactory.newInstance(); + lFactory.setNamespaceAware(true); + XmlPullParser lXmlPullParser = lFactory.newPullParser(); + lXmlPullParser.setInput(new StringReader(chaine)); + int lEventType = lXmlPullParser.getEventType(); + while(lEventType != XmlPullParser.END_DOCUMENT) { + switch(lEventType) { + case XmlPullParser.START_DOCUMENT : + case XmlPullParser.END_DOCUMENT : + break; + case XmlPullParser.START_TAG : + lTagName = lXmlPullParser.getName(); + if (lTagName.equals("EQUIPE")) { + this.pNomEquipe = lXmlPullParser.getAttributeValue(null, "nom"); + } + else if (lTagName.equals("COUREUR")) { + if (lXmlPullParser.getAttributeCount() == 1) { + lActif = lXmlPullParser.getAttributeValue(null, "actif").equals("YES"); + } + else { + } + } + else { + } + break; + case XmlPullParser.END_TAG : + lTagName = lXmlPullParser.getName(); + if (lTagName.equals("COUREUR")) { + if (pListeCoureurs.size() < pNbCoureurMax) { + pListeCoureurs.add(lText); + if (lActif) { + pListeCoureursActifs.add(lText); + pListeEtatsCoureurs.add(true); + } + else { + pListeEtatsCoureurs.add(false); + } + } + else { + } + } + else { + } + break; + case XmlPullParser.TEXT : + lText = lXmlPullParser.getText(); + break; + default : ; + } + lEventType = lXmlPullParser.next(); + } + Log.i("", "Fichier XML parsé"); + } + catch(XmlPullParserException e) { + Log.i("", "Erreur en parsant fichier XML"); + pListeCoureurs.clear(); + pListeCoureursActifs.clear(); + pListeEtatsCoureurs.clear(); + } + catch(IOException e) { + pListeCoureurs.clear(); + pListeCoureursActifs.clear(); + pListeEtatsCoureurs.clear(); + } + } + + // Constructeur + public Equipe(boolean lireXML, int nombre_coureur) { + this.pNbCoureurMax = nombre_coureur; + this.pLireXML = lireXML; + this.pContext = null; + pListeCoureurs = new ArrayList(nombre_coureur); + pListeCoureursActifs = new ArrayList(nombre_coureur); + pListeEtatsCoureurs = new ArrayList(nombre_coureur); + } + + // Méthode lireXML + public void lireXML(Context context) { + String lChaine; + this.pContext = context; + if (this.pLireXML) { + this.pLireXML = false; + lChaine = lireXMLEquipe(); + if (lChaine != null) { + ParserXML(lChaine); + } + else { + } + } + else { + } + } + + // Méthode lireNomEquipe + // Retourne le nom de l'équipe + public String lireNomEquipe() { + return (pNomEquipe); + } + + // Méthode ecrireNomEquipe + // Ecrit le nom de l'équipe + public void ecrireNomEquipe(String nom) { + this.pNomEquipe = nom; + } + + // Méthode lireCoureur + // Retourne le coureur à la position + public String lireCoureur(int position) { + return (pListeCoureurs.get(position)); + } + + // Méthode lireEtatActif + // Retourne l'état actif à la position + public Boolean lireEtatActif(int position) { + return (pListeEtatsCoureurs.get(position)); + } + + // Méthode ecrireEtatActif + // Ecrit l'état actif à la position et met à jour la liste des coureurs actifs + public void ecrireEtatActif(int position, boolean actif) { + int i; + pListeEtatsCoureurs.set(position, actif); + pListeCoureursActifs.clear(); + for(i=0;i < pListeCoureurs.size();i++) { + if (pListeEtatsCoureurs.get(i)) { + pListeCoureursActifs.add(pListeCoureurs.get(i)); + } + else { + } + } + } + + // Méthode lireListeCoureurs + // Retourne la liste des coureurs + public ArrayList lireListeCoureurs() { + return (pListeCoureurs); + } + + // Méthode lireListeCoureursActifs + // Retourne la liste de coureurs actifs + public ArrayList lireListeCoureursActifs() { + return (pListeCoureursActifs); + } + + // Méthode ajouterCoureur + // Ajoute le coureur dans l'équipe si cela est possible + // Retourne true si le coureur a été ajouté, false sinon + public boolean ajouterCoureur(String coureur) { + if (pListeCoureurs.size() < pNbCoureurMax) { + pListeCoureurs.add(coureur); + pListeCoureursActifs.add(coureur); + pListeEtatsCoureurs.add(true); + return (ecrireXMLEquipe()); + } + else { + return (false); + } + } + + // Méthode supprimerCoureur + // Supprime un coureur à la position + public void supprimerCoureur(int position) { + if (position <= pListeCoureurs.size()) { + pListeCoureurs.remove(position); + pListeCoureursActifs.remove(position); + pListeEtatsCoureurs.remove(position); + ecrireXMLEquipe(); + } + else { + } + } + + // Methode lireProchainCoureur + // Retourne le prochain coureur actif de la liste + public String lireProchainCoureurActif(String coureur) { + int position = pListeCoureursActifs.indexOf(coureur) + 1; + if (position >= pListeCoureursActifs.size()) { + position = 0; + } + else { + } + return (pListeCoureursActifs.get(position)); + } + + // Méthode inverserCoureurs + // Inverse la position de 2 coureurs dans toutes les listes + public void inverserCoureurs(int position1, int position2) { + int i; + boolean lActif = pListeEtatsCoureurs.get(position1); + String lCoureur = pListeCoureurs.get(position1); + pListeEtatsCoureurs.set(position1, pListeEtatsCoureurs.get(position2)); + pListeCoureurs.set(position1, pListeCoureurs.get(position2)); + pListeEtatsCoureurs.set(position2, lActif); + pListeCoureurs.set(position2, lCoureur); + pListeCoureursActifs.clear(); + for(i=0;i < pListeCoureurs.size();i++) { + if (pListeEtatsCoureurs.get(i)) { + pListeCoureursActifs.add(pListeCoureurs.get(i)); + } + else { + } + } + ecrireXMLEquipe(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Pager.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Pager.java new file mode 100644 index 0000000..b705978 --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Pager.java @@ -0,0 +1,45 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; + +// Class Pager +public class Pager extends FragmentStatePagerAdapter { + // Attributs privés + int tabCount; + TabEquipe pTabEquipe; + TabCourse pTabCourse; + TabResultats pTabResultats; + + //Constructeur + public Pager(FragmentManager fm, int tabCount) { + super(fm); + this.tabCount = tabCount; + this.pTabEquipe = new TabEquipe(); + this.pTabCourse = new TabCourse(); + this.pTabResultats = new TabResultats(); + } + + // Méthode getItem + @Override + public Fragment getItem(int position) { + //Returning the current tabs + switch (position) { + case 0: + return (this.pTabEquipe); + case 1: + return (this.pTabCourse); + case 2: + return (this.pTabResultats); + default: + return (null); + } +} + // Méthode getCount + // Retourne le nombre d'onglets + @Override + public int getCount() { + return (tabCount); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ParametresActivity.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ParametresActivity.java new file mode 100644 index 0000000..4f9e6cb --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ParametresActivity.java @@ -0,0 +1,119 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.CheckBox; +import android.widget.SeekBar; +import android.support.v7.widget.Toolbar; +import android.widget.TextView; + +// Classe ParametresActivity +public class ParametresActivity extends AppCompatActivity { + // TODO Implementer la prise en compte de la checkbox Sortir + // Attributs privés + private Vibreur pVibreur; + private Toolbar pToolbar; + private CheckBox pCheckBoxVibreur; + private SeekBar pSeekBarRetard; + private SeekBar pSeekBarDuree; + private TextView pTextViewRetard; + private TextView pTextViewDuree; + private CheckBox pCheckBoxSortir; + + // Méthode onCreate + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_parametres); + pToolbar = (Toolbar) findViewById(R.id.toolbar); + pCheckBoxVibreur = (CheckBox) findViewById(R.id.checkBoxVibreur); + pSeekBarRetard = (SeekBar) findViewById(R.id.seekBarRetard); + pSeekBarDuree = (SeekBar) findViewById(R.id.seekBarDuree); + pTextViewRetard = (TextView) findViewById(R.id.textViewRetard); + pTextViewDuree = (TextView) findViewById(R.id.textViewDuree); + pCheckBoxSortir = (CheckBox) findViewById(R.id.checkBoxSortir); + setSupportActionBar(pToolbar); + Intent lIntent = getIntent(); + pVibreur = new Vibreur(lIntent.getBooleanExtra("vibreur_actif_in", true), + lIntent.getLongExtra("vibreur_retard_in", (long)66), + lIntent.getLongExtra("vibreur_duree_in", (long)20)); + pSeekBarRetard.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + int lProgress = 0; + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + lProgress = progress; + pTextViewRetard.setText(String.format("%d %%", lProgress)); + pVibreur.ecrireRetard((long) lProgress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + pTextViewRetard.setText(String.format("%d %%", lProgress)); + pVibreur.ecrireRetard((long) lProgress); + } + }); + pSeekBarDuree.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + int lProgress = 0; + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (progress < 10) { + lProgress = 10; + pSeekBarDuree.setProgress(10); + } + else { + lProgress = progress; + } + pTextViewDuree.setText(String.format("%d s", lProgress / 10)); + pVibreur.ecrireDuree((long) lProgress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + pTextViewDuree.setText(String.format("%d s", lProgress / 10)); + pVibreur.ecrireDuree((long) lProgress); + } + }); + pCheckBoxVibreur.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + pVibreur.ecrireEtatActif(pCheckBoxVibreur.isChecked()); + pSeekBarRetard.setEnabled(pCheckBoxVibreur.isChecked()); + pSeekBarDuree.setEnabled(pCheckBoxVibreur.isChecked()); + } + }); + if (pVibreur.lireEtatActif()) { + pCheckBoxVibreur.setChecked(true); + pSeekBarRetard.setEnabled(true); + pSeekBarDuree.setEnabled(true); + } + else { + pCheckBoxVibreur.setChecked(false); + pSeekBarRetard.setEnabled(false); + pSeekBarDuree.setEnabled(false); + } + pSeekBarRetard.setProgress((int) pVibreur.lireRetard()); + pTextViewRetard.setText(String.format("%d %%", (int) pVibreur.lireRetard())); + pSeekBarDuree.setProgress((int) pVibreur.lireDuree()); + pTextViewDuree.setText(String.format("%d s", (int) (pVibreur.lireDuree() / 10))); + } + + // Méthode finish + // On écrit l'état et la durée du vibreur dans l'intent + @Override + public void finish() { + Intent lIntent = new Intent(); + lIntent.putExtra("vibreur_actif_out", pVibreur.lireEtatActif()); + lIntent.putExtra("vibreur_retard_out", pVibreur.lireRetard()); + lIntent.putExtra("vibreur_duree_out", pVibreur.lireDuree()); + setResult(RESULT_OK, lIntent); + super.finish(); + } +} diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Resultat.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Resultat.java new file mode 100644 index 0000000..1cb83d9 --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Resultat.java @@ -0,0 +1,31 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +// Class Resultat +public class Resultat { + // Attributs privés + int pNumero; + String pNom; + long pDuree; + + // Constructeur + public Resultat(int numero, String nom, long duree) { + this.pNumero = numero; + this.pNom = nom; + this.pDuree = duree; + } + + // Méthode LireNuméro + public int lireNuméro() { + return this.pNumero; + } + + // Méthode lireNomEquipe + public String lireNom() { + return this.pNom; + } + + // Méthode lireRetard + public long lireDuree() { + return this.pDuree; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ResultatAdapter.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ResultatAdapter.java new file mode 100644 index 0000000..1cade0b --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ResultatAdapter.java @@ -0,0 +1,63 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.BaseAdapter; +import android.widget.ListAdapter; +import android.widget.TextView; + +import java.util.ArrayList; + +// Class ResultatAdapter +public class ResultatAdapter extends ArrayAdapter { + // Attributs privés + private Context pContext; + private int pLayoutResourceId; + private LayoutInflater pInflater; + private ArrayList pListeResultats; + + // Constructeur + public ResultatAdapter(Context context, int resource, ArrayList listeResultats) { + super(context, resource, listeResultats); + this.pContext = context; + this.pLayoutResourceId = resource; + this.pInflater = LayoutInflater.from(context); + pListeResultats = listeResultats; + } + @Override + public int getCount() { + return(pListeResultats.size()); + } + + @Override + public Resultat getItem(int position) { + return(super.getItem(position)); + } + + @Override + public long getItemId(int position) { + return(super.getItemId(position)); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View lView = convertView; + if (lView == null) { + lView = pInflater.inflate(pLayoutResourceId, parent, false); + } + else { + } + Resultat lResultat = pListeResultats.get(position); + long lDuree = lResultat.lireDuree(); + TextView lTextViewNumeroTour = (TextView) lView.findViewById(R.id.textViewNumeroTour); + TextView lTextViewTemps = (TextView) lView.findViewById(R.id.textViewTemps); + TextView lTextViewNom = (TextView) lView.findViewById(R.id.textViewNom); + lTextViewNumeroTour.setText(String.format("%03d", lResultat.lireNuméro())); + lTextViewTemps.setText(String.format("%02d min %02d sec", (lDuree / (60 * 1000)) % 60, (lDuree / 1000) % 60)); + lTextViewNom.setText(String.format("%s", lResultat.lireNom())); + return (lView); + } +} diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ResultatSQLiteOpenHelper.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ResultatSQLiteOpenHelper.java new file mode 100644 index 0000000..9bd255b --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/ResultatSQLiteOpenHelper.java @@ -0,0 +1,38 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +// Class ResultatSQLiteOpenHelper +public class ResultatSQLiteOpenHelper extends SQLiteOpenHelper { + // Attributs + private final static int kVersion = 1; + private final static String kNomDeFichier = "chronos24hLeMans.db"; + + // Constructeur + public ResultatSQLiteOpenHelper(Context context) { + super(context, kNomDeFichier, null, kVersion); + } + + @Override + public void onCreate(SQLiteDatabase db) { + String lSQLFillTable = "CREATE TABLE IF NOT EXISTS RESULTAT (id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT, chrono TEXT, heure_debut TEXT, heure_fin TEXT);"; + db.execSQL(lSQLFillTable); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + int i; + for(i = oldVersion;i < newVersion;i++) { + if ((i + 1) == 2) { + + } + else if ((i + 1 )== 3) { + + } + else { + } + } + } +} diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/StatCoureur.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/StatCoureur.java new file mode 100644 index 0000000..9d3bc8f --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/StatCoureur.java @@ -0,0 +1,57 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +// Class StatCoureur +public class StatCoureur { + // Attributs privés + private String pCoureur; + private int pNbTour; + private long pTempsMin; + private long pTempsMoyen; + private long pTempsMax; + + // Constructeur + public StatCoureur() { + pCoureur = new String(""); + pNbTour = 0; + pTempsMin = Long.MAX_VALUE; + pTempsMoyen = 0; + pTempsMax = 0; + } + + // Méthode ajouterStat + public void ajouterStat(String coureur, long temps) { + pCoureur = coureur; + if (temps < pTempsMin) { + pTempsMin = temps; + } + else { + } + if (temps > pTempsMax) { + pTempsMax = temps; + } + else { + } + pTempsMoyen = (pNbTour * pTempsMoyen + temps) / (pNbTour + 1); + pNbTour++; + } + + // Méthode lireNom + // Retourne le nom du coureur + public String lireNom() { return (pCoureur); } + + // Méthode lireNombreTours + // Retourne le nombre de tours + public int lireNombreTours() { return (pNbTour); } + + // Méthode lireTempsMini + // Retourne le temps mini + public long lireTempsMini() { return (pTempsMin); } + + // Méthode lireTempsMoyen + // Retourne le temps moyen + public long lireTempsMoyen() { return (pTempsMoyen); } + + // Méthode lireTempsMax + // Retourne le temps max + public long lireTempsMax() { return (pTempsMax); } +} diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabCourse.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabCourse.java new file mode 100644 index 0000000..a1aa6dc --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabCourse.java @@ -0,0 +1,293 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.os.SystemClock; +import android.os.Vibrator; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.Chronometer; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.Date; + +// Class TabCourse +public class TabCourse extends Fragment { + // Classe privée + private class AlerteCoureur extends CountDownTimer { + // Attributs privés + private Vibrator pVibreur; + + // Constructeur + public AlerteCoureur(long startTime, long interval) { + super(startTime, interval); + pVibreur = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); + } + + // Méthode onTick + // Ne rien faire + @Override + public void onTick(long millisUntilFinished) { } + + // Méthode onFinish + // Faire vibrer le téléphone pendant 2 sec + @Override + public void onFinish() { + if (pVibreur.hasVibrator()) { + pVibreur.vibrate(Chronos24hLeMansActivity.aVibreur.lireDuree() * 100); + } + else { + } + } + } + // Attributs privés + private AlerteCoureur pAlerteCoureur; + private boolean pCourseDemarree; + private boolean pPauseDemarree; + private long pHeureDebut; + private Date pDateDebut; + private long pHeureFin; + private Date pDateFin; + private long pHeurePause; + private CoureurAdapter pCoureurAdapter; + private Button pBoutonDemarrer; + private Button pBoutonPause; + private Button pBoutonArreter; + private TextView pTextViewNbTour; + private TextView pTextViewNonCoureurEnCourse; + private Chronometer pChronometre; + private Button pBoutonContinuer; + private Button pBoutonPasserRelai; + private TextView pTextViewProchainCoureur; + private ListView pListViewProchainCoureur; + private CountDownTimer pCountDownTimerContinuer; + private CountDownTimer pCountDownTimerPasserRelai; + + // Méthode programmerAlerteCoureur + private void programmerAlerteCoureur(String nom) { + long lTemps; + // Lire le temps moyen du coureur + lTemps = TabResultats.lireTempsMoyenCoureur(nom); + // Si le temps moyen est non nul (1er tour) et le vibreur est activé alors programmer l'alerte et demmarer l'alerte + if ((lTemps != 0) && (Chronos24hLeMansActivity.aVibreur.lireEtatActif())) { + pAlerteCoureur = new AlerteCoureur(Chronos24hLeMansActivity.aVibreur.lireRetard() * lTemps / 100, lTemps); + pAlerteCoureur.start(); + } + else { + } + } + + // Méthode arreterAlerteCoureur + private void arreterAlerteCoureur() { + // Si l'alerte a été programmée alors arrêter l'alerte + if (pAlerteCoureur != null) { + pAlerteCoureur.cancel(); + } + else { + } + } + + // Méthode onCreate + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + pCourseDemarree = false; + pPauseDemarree = false; + pAlerteCoureur = null; + } + + // Méthode onCreateView + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View lView = inflater.inflate(R.layout.tab_course, container, false); + pCoureurAdapter = new CoureurAdapter(lView.getContext(), R.layout.list_view_coureur, R.id.textViewCoureur, TabEquipe.pEquipe.lireListeCoureursActifs()); + pBoutonDemarrer = (Button) lView.findViewById(R.id.ButtonDemarrer); + pBoutonPause = (Button) lView.findViewById(R.id.ButtonPause); + pBoutonArreter = (Button) lView.findViewById(R.id.ButtonArreter); + pTextViewNbTour = (TextView) lView.findViewById(R.id.textViewNbTour); + pTextViewNonCoureurEnCourse = (TextView) lView.findViewById(R.id.textViewNomCoureurEnCourse); + pChronometre = (Chronometer) lView.findViewById(R.id.chronometer); + pBoutonContinuer = (Button) lView.findViewById(R.id.buttonContinuer); + pBoutonPasserRelai = (Button) lView.findViewById(R.id.buttonPasserRelai); + pTextViewProchainCoureur = (TextView) lView.findViewById(R.id.textViewProchainCoureur); + pListViewProchainCoureur = (ListView) lView.findViewById(R.id.listViewProchainCoureur); + pListViewProchainCoureur.setAdapter(pCoureurAdapter); + // TODO Mettre en paramètres la tempo de 5s + pCountDownTimerContinuer = new CountDownTimer(5000,5000) { + @Override + public void onTick(long millisUntilFinished) { } + + @Override + public void onFinish() { + pBoutonContinuer.setEnabled(true); + } + }; + pCountDownTimerPasserRelai = new CountDownTimer(5000,5000) { + @Override + public void onTick(long millisUntilFinished) { } + + @Override + public void onFinish() { + pBoutonPasserRelai.setEnabled(true); + } + }; + if (! pCourseDemarree) { + pBoutonDemarrer.setEnabled(false); + pBoutonPause.setEnabled(false); + pBoutonArreter.setEnabled(false); + pBoutonContinuer.setEnabled(false); + pBoutonPasserRelai.setEnabled(false); + } + else { + } + pBoutonDemarrer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + pBoutonDemarrer.setEnabled(false); + pBoutonArreter.setEnabled(true); + pBoutonPause.setEnabled(true); + pBoutonContinuer.setEnabled(true); + pBoutonPasserRelai.setEnabled(true); + pTextViewNonCoureurEnCourse.setText(pTextViewProchainCoureur.getText()); + pHeureDebut = SystemClock.elapsedRealtime(); + pDateDebut = new Date(); + pChronometre.setBase(pHeureDebut); + pChronometre.start(); + pTextViewProchainCoureur.setText(TabEquipe.pEquipe.lireProchainCoureurActif(pTextViewProchainCoureur.getText().toString())); + pTextViewProchainCoureur.setBackgroundColor(Color.parseColor("#0080FF")); + } + }); + pBoutonPause.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (! pPauseDemarree) { + pHeurePause = SystemClock.elapsedRealtime() - pChronometre.getBase(); + pChronometre.stop(); + arreterAlerteCoureur(); + pBoutonPause.setText("Reprendre"); + pBoutonArreter.setEnabled(false); + pBoutonContinuer.setEnabled(false); + pBoutonPasserRelai.setEnabled(false); + pPauseDemarree = true; + } + else { + pChronometre.setBase(SystemClock.elapsedRealtime() - pHeurePause); + pChronometre.start(); + pBoutonPause.setText("Pause"); + pBoutonArreter.setEnabled(true); + pBoutonContinuer.setEnabled(true); + pBoutonPasserRelai.setEnabled(true); + pPauseDemarree = false; + } + } + }); + pBoutonArreter.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + int lNbTour; + long lDuree; + pBoutonDemarrer.setEnabled(false); + pBoutonPause.setEnabled(false); + pBoutonArreter.setEnabled(false); + pBoutonContinuer.setEnabled(false); + pBoutonPasserRelai.setEnabled(false); + pChronometre.stop(); + arreterAlerteCoureur(); + pHeureFin = SystemClock.elapsedRealtime(); + pDateFin = new Date(); + lDuree = pHeureFin - pHeureDebut; + lNbTour = TabResultats.ajouterResultat(pTextViewNonCoureurEnCourse.getText().toString(), pDateDebut, pDateFin, lDuree); + pTextViewNbTour.setText(String.format("%03d", lNbTour)); + pTextViewNonCoureurEnCourse.setText(""); + pTextViewProchainCoureur.setText(""); + pTextViewProchainCoureur.setBackgroundColor(Color.RED); + pCourseDemarree = false; + } + }); + pBoutonContinuer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int lNbTour; + long lDuree; + pChronometre.stop(); + arreterAlerteCoureur(); + pHeureFin = SystemClock.elapsedRealtime(); + pDateFin = new Date(); + lDuree = pHeureFin - pHeureDebut; + pChronometre.setBase(pHeureFin); + lNbTour = TabResultats.ajouterResultat(pTextViewNonCoureurEnCourse.getText().toString(), pDateDebut, pDateFin, lDuree); + pTextViewNbTour.setText(String.format("%03d", lNbTour)); + pDateDebut = new Date(); + pHeureDebut = pHeureFin; + pChronometre.start(); + programmerAlerteCoureur(pTextViewNonCoureurEnCourse.getText().toString()); + pBoutonContinuer.setEnabled(false); + pCountDownTimerContinuer.start(); + } + }); + pBoutonPasserRelai.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + int lNbTour; + int position; + long lDuree; + if (pTextViewProchainCoureur.getText().equals("")) { + Toast.makeText(view.getContext(), "Sélectionner un coureur dans la liste", Toast.LENGTH_SHORT).show(); + } + else { + pChronometre.stop(); + arreterAlerteCoureur(); + pHeureFin = SystemClock.elapsedRealtime(); + pDateFin = new Date(); + lDuree = pHeureFin - pHeureDebut; + pChronometre.setBase(pHeureFin); + lNbTour = TabResultats.ajouterResultat(pTextViewNonCoureurEnCourse.getText().toString(), pDateDebut, pDateFin, lDuree); + pTextViewNbTour.setText(String.format("%03d", lNbTour)); + pDateDebut = new Date(); + pHeureDebut = pHeureFin; + pChronometre.start(); + programmerAlerteCoureur(pTextViewProchainCoureur.getText().toString()); + pTextViewNonCoureurEnCourse.setText(pTextViewProchainCoureur.getText()); + pTextViewProchainCoureur.setText(TabEquipe.pEquipe.lireProchainCoureurActif(pTextViewProchainCoureur.getText().toString())); + pTextViewProchainCoureur.setBackgroundColor(Color.parseColor("#0080FF")); + pBoutonPasserRelai.setEnabled(false); + pCountDownTimerPasserRelai.start(); + } + } + }); + pListViewProchainCoureur.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + //pTextViewProchainCoureur.setText(TabEquipe.pEquipe.lireCoureur(position)); + pTextViewProchainCoureur.setText(pListViewProchainCoureur.getItemAtPosition(position).toString()); + pTextViewProchainCoureur.setBackgroundColor(Color.parseColor("#CECECE")); + if (! pCourseDemarree) { + pBoutonDemarrer.setEnabled(true); + pCourseDemarree = true; + } + else { + } + return (true); + } + }); + //Returning the layout file after inflating + //Change R.layout.tab_course in you classes + return (lView); + } + + // Méthode onResume + @Override + public void onResume() { + super.onResume(); + pCoureurAdapter.notifyDataSetChanged(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabEquipe.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabEquipe.java new file mode 100644 index 0000000..79425ec --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabEquipe.java @@ -0,0 +1,199 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +// Class TabEquipe +public class TabEquipe extends Fragment { + // Attributs privés + private final int kNbCoureurMax = 20; + private int pNbCoureurs; + private int pCoureurSelectionne; + private CoureurAdapter pCoureurAdapter; + private EditText pEditTextNomEquipe; + private TextView pTextViewNbCoureurs; + private EditText pEditTextNomCoureur; + private Button pBoutonAjouter; + private ImageButton pBoutonMonter; + private ImageButton pBoutonDescendre; + private CheckBox pBoiteActif; + private ListView pListViewEquipe; + // Attributs publics + public static Equipe pEquipe; + + // Constructeur + public TabEquipe() { + pNbCoureurs = 0; + pCoureurSelectionne = 0; + pEquipe = new Equipe(true, kNbCoureurMax); + } + + //Méthode onCreateView + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View lView = inflater.inflate(R.layout.tab_equipe, container, false); + pEquipe.lireXML(getActivity().getApplicationContext()); + pNbCoureurs = pEquipe.lireListeCoureurs().size(); + pCoureurAdapter = new CoureurAdapter(lView.getContext(), R.layout.list_view_coureur, R.id.textViewCoureur, pEquipe.lireListeCoureurs()); + pEditTextNomEquipe = (EditText) lView.findViewById(R.id.editTextNomEquipe); + if (pEquipe.lireNomEquipe() != null) { + pEditTextNomEquipe.setText(pEquipe.lireNomEquipe()); + } + else { + } + pTextViewNbCoureurs = (TextView) lView.findViewById(R.id.textViewNbCoureurs); + pTextViewNbCoureurs.setText(String.format("%d", pNbCoureurs)); + pEditTextNomCoureur = (EditText) lView.findViewById(R.id.editTextNomCoureur); + pBoutonAjouter = (Button) lView.findViewById(R.id.buttonAjouter); + pBoutonMonter = (ImageButton) lView.findViewById(R.id.imageButtonMonter); + pBoutonDescendre = (ImageButton) lView.findViewById(R.id.imageButtonDescendre); + pBoiteActif = (CheckBox) lView.findViewById(R.id.checkBoxActif); + pListViewEquipe = (ListView) lView.findViewById(R.id.listViewEquipe); + pListViewEquipe.setAdapter(pCoureurAdapter); + pBoutonAjouter.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (pEditTextNomCoureur.length() == 0) { + Toast.makeText(view.getContext(), "Entrez un nom pour ajouter", Toast.LENGTH_LONG).show(); + } + else if (! pEquipe.ajouterCoureur(pEditTextNomCoureur.getText().toString())) { + Toast.makeText(view.getContext(), "Nombre maximum de coureurs atteint", Toast.LENGTH_LONG).show(); + } + else { + pNbCoureurs++; + pTextViewNbCoureurs.setText(String.format("%d", pNbCoureurs)); + pCoureurAdapter.notifyDataSetChanged(); + Toast.makeText(view.getContext(), String.format("Coureur %s ajouté", pEditTextNomCoureur.getText().toString()), Toast.LENGTH_SHORT).show(); + pEditTextNomCoureur.setText(""); + } + } + }); + pBoiteActif.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Attention, l'etat de la CheckBox semble être modifié automatiquement + // C'est pour cela que le code qui suit fait l'inverse de ce qui est prévu + if (pBoiteActif.isChecked()) { + pEquipe.ecrireEtatActif(pCoureurSelectionne, true); + } + else { + pEquipe.ecrireEtatActif(pCoureurSelectionne, false); + } + } + }); + pBoutonMonter.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + pEquipe.inverserCoureurs(pCoureurSelectionne - 1, pCoureurSelectionne); + pCoureurAdapter.notifyDataSetChanged(); + Toast.makeText(v.getContext(), String.format("Inverser %d et %d", pCoureurSelectionne, pCoureurSelectionne - 1), Toast.LENGTH_SHORT).show(); + } + }); + pBoutonDescendre.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + pEquipe.inverserCoureurs(pCoureurSelectionne, pCoureurSelectionne + 1); + pCoureurAdapter.notifyDataSetChanged(); + Toast.makeText(v.getContext(), String.format("Inverser %d et %d", pCoureurSelectionne, pCoureurSelectionne + 1), Toast.LENGTH_SHORT).show(); + } + }); + pEditTextNomEquipe.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View view, boolean hasFocus) { + if (! hasFocus) { + if (pEditTextNomEquipe.getText().length() != 0) { + pEquipe.ecrireNomEquipe(pEditTextNomEquipe.getText().toString()); + Toast.makeText(view.getContext(), String.format("Nom de l'équipe %s enregistré", pEditTextNomEquipe.getText().toString()), Toast.LENGTH_LONG).show(); + } + else { + } + } + } + }); + pListViewEquipe.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + // TODO Changer la couleur de la ligne sélectionnée + pCoureurSelectionne = position; + if (pNbCoureurs == 1) { + pBoutonMonter.setVisibility(View.INVISIBLE); + pBoutonDescendre.setVisibility(View.INVISIBLE); + } + else { + if (position == 0) { + pBoutonMonter.setVisibility(View.INVISIBLE); + pBoutonDescendre.setVisibility(View.VISIBLE); + } + else if ((position + 1) == pNbCoureurs) { + pBoutonMonter.setVisibility(View.VISIBLE); + pBoutonDescendre.setVisibility(View.INVISIBLE); + + } + else { + pBoutonMonter.setVisibility(View.VISIBLE); + pBoutonDescendre.setVisibility(View.VISIBLE); + } + } + pBoiteActif.setVisibility(View.VISIBLE); + pBoiteActif.setChecked(pEquipe.lireEtatActif(position)); + //Toast.makeText(view.getContext(), String.format("Selection %d", position), Toast.LENGTH_SHORT).show(); + } + }); + pListViewEquipe.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + final int lPosition = position; + final View lView = view; + new AlertDialog.Builder(view.getContext()) + .setTitle("Confirmation") + .setMessage(String.format("Suppression coureur %s ?", pEquipe.lireCoureur(lPosition))) + .setPositiveButton("OUI", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + Toast.makeText(lView.getContext(), String.format("Coureur %s supprimé", pEquipe.lireCoureur(lPosition)), Toast.LENGTH_LONG).show(); + pEquipe.supprimerCoureur(lPosition); + pNbCoureurs--; + pTextViewNbCoureurs.setText(String.format("%d", pNbCoureurs)); + pCoureurAdapter.notifyDataSetChanged(); + } + }) + .setNegativeButton("NON", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + } + }).show(); + return (true); + } + }); + //Returning the layout file after inflating + //Change R.layout.tab_equipe in you classes + return (lView); + } + + @Override + public void onPause() { + super.onPause(); + pBoutonMonter.setVisibility(View.INVISIBLE); + pBoutonDescendre.setVisibility(View.INVISIBLE); + pBoiteActif.setVisibility(View.INVISIBLE); + } + + @Override + public void onResume() { + super.onResume(); + pBoutonMonter.setVisibility(View.INVISIBLE); + pBoutonDescendre.setVisibility(View.INVISIBLE); + pBoiteActif.setVisibility(View.INVISIBLE); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabResultats.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabResultats.java new file mode 100644 index 0000000..4c46b0a --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/TabResultats.java @@ -0,0 +1,150 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +import android.content.ContentValues; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.GridView; +import android.widget.TextView; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +// Class TabResultats +public class TabResultats extends Fragment { + // Atributs privés + private final int kNbResultatMax = 300; + // TODO Supprimer la déclaration en double + private final int kNbCoureurMax = 20; + private static ResultatAdapter pResultatAdapter; + private TextView pTextViewNomCoureur; + private TextView pTextViewNbTour; + private TextView pTextViewTempsMini; + private TextView pTextViewTempsMoyen; + private TextView pTextViewTempsMax; + private GridView pGridViewResultats; + private static ArrayList pListeResultats; + private static ArrayList pListeStatCoureurs; + + // Constructeur + public TabResultats() { + pListeResultats = new ArrayList(kNbResultatMax); + pListeStatCoureurs = new ArrayList(kNbCoureurMax); + } + + // Méthode onCreateView + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View lView = inflater.inflate(R.layout.tab_resultats, container, false); + pResultatAdapter = new ResultatAdapter(lView.getContext(), R.layout.grid_view_resultat, pListeResultats); + pTextViewNomCoureur = (TextView) lView.findViewById(R.id.textViewNomCoureur); + pTextViewNbTour = (TextView) lView.findViewById(R.id.textViewNbTour); + pTextViewTempsMini = (TextView) lView.findViewById(R.id.textViewTempsMini); + pTextViewTempsMoyen = (TextView) lView.findViewById(R.id.textViewTempsMoyen); + pTextViewTempsMax = (TextView) lView.findViewById(R.id.textViewTempsMax); + pGridViewResultats = (GridView) lView.findViewById(R.id.gridViewResultats); + pGridViewResultats.setAdapter(pResultatAdapter); + pGridViewResultats.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + int lPosition; + String lNomCoureur; + StatCoureur lStatCoureur; + lNomCoureur = pListeResultats.get(position).lireNom(); + lPosition = positionCoureur(lNomCoureur); + if (lPosition == -1) { + pTextViewNomCoureur.setText(lNomCoureur); + pTextViewNbTour.setText("-"); + pTextViewTempsMini.setText("-"); + pTextViewTempsMoyen.setText("-"); + pTextViewTempsMax.setText("-"); + } + else { + lStatCoureur = pListeStatCoureurs.get(lPosition); + pTextViewNomCoureur.setText(lStatCoureur.lireNom()); + pTextViewNbTour.setText(String.format("%02d", lStatCoureur.lireNombreTours())); + pTextViewTempsMini.setText(String.format("%02d:%02d", (lStatCoureur.lireTempsMini() / (60 * 1000)) % 60, (lStatCoureur.lireTempsMini() / 1000) % 60)); + pTextViewTempsMoyen.setText(String.format("%02d:%02d", (lStatCoureur.lireTempsMoyen() / (60 * 1000)) % 60, (lStatCoureur.lireTempsMoyen() / 1000) % 60)); + pTextViewTempsMax.setText(String.format("%02d:%02d", (lStatCoureur.lireTempsMax() / (60 * 1000)) % 60, (lStatCoureur.lireTempsMax() / 1000) % 60)); + } + // Toast.makeText(view.getContext(), String.format("Position sélectionnée : %d", position), Toast.LENGTH_SHORT).show(); + } + }); + return (lView); + } + + // Méthode positionCoureur + // Retourne la position du coureur dans la liste des stats en fonction de son nom, -1 si le coureur n'a pas été trouvé + private int positionCoureur(String nom) { + for(StatCoureur lStatCoureur : pListeStatCoureurs) { + if (nom.equals(lStatCoureur.lireNom())) { + return (pListeStatCoureurs.indexOf(lStatCoureur)); + } + else { + } + } + return (-1); + } + + // Méthode lireTempsMoyenCoureur + // Retourne le temps moyen du coureur, 0 si le coureur n'a pas été trouvé + public static long lireTempsMoyenCoureur(String nom) { + for(StatCoureur lStatCoureur : pListeStatCoureurs) { + if (nom.equals(lStatCoureur.lireNom())) { + return (lStatCoureur.lireTempsMoyen()); + } + else { + } + } + return (0); + } + // Méthode ajouterResultat + // Ajoute un résultat à la liste des résutats + public static int ajouterResultat(String nom, Date debut, Date fin, long duree) { + int i = 0; + int lPosition = -1; + // Ajouter le résultat à la liste des résultats, au début et affichage + Resultat lResutat = new Resultat(pListeResultats.size() + 1, nom, duree); + pListeResultats.add(0, lResutat); + pResultatAdapter.notifyDataSetChanged(); + // Ajouter la statistique du coureur + StatCoureur lStatCoureur; + while((i < pListeStatCoureurs.size()) && (lPosition == -1)) { + if (pListeStatCoureurs.get(i).lireNom().equals(nom)) { + lPosition = i; + } + else { + } + i++; + } + if (lPosition == -1) { + lStatCoureur = new StatCoureur(); + lStatCoureur.ajouterStat(nom, duree); + pListeStatCoureurs.add(lStatCoureur); + } + else { + lStatCoureur = pListeStatCoureurs.get(lPosition); + lStatCoureur.ajouterStat(nom, duree); + pListeStatCoureurs.set(lPosition, lStatCoureur); + } + // Ecrire dans la base de données + ContentValues lValues = new ContentValues(); + SimpleDateFormat lSDF = new SimpleDateFormat("dd/MM/yyyy hh:mm"); + lValues.put("nom", nom); + lValues.put("chrono", String.format("%02d:%02d", (duree / (60 * 1000)) % 60, (duree / 1000) % 60)); + lValues.put("heure_debut", lSDF.format(debut)); + lValues.put("heure_fin", lSDF.format(fin)); + Chronos24hLeMansActivity.insererDatabase(lValues); + return (pListeResultats.size()); + } + + @Override + public void onResume() { + super.onResume(); + pResultatAdapter.notifyDataSetChanged(); + } +} + diff --git a/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Vibreur.java b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Vibreur.java new file mode 100644 index 0000000..1ae952a --- /dev/null +++ b/app/src/main/java/com/assistanceinformatiquetoulouse/chronos24hlemans/Vibreur.java @@ -0,0 +1,41 @@ +package com.assistanceinformatiquetoulouse.chronos24hlemans; + +// Class Vibreur +public class Vibreur { + // Attributs privés + private long pRetard; + private long pDuree; + private Boolean pEtatActif; + + // Constructeur + public Vibreur() { + pEtatActif = true; + pRetard = (long)66; + pDuree = (long)20; + } + + // Constructeur + public Vibreur(Boolean etatActif, long retard, long duree) { + pEtatActif = etatActif; + pRetard = retard; + pDuree = duree; + } + + // Méthode lireEtatActif + public Boolean lireEtatActif() { return (pEtatActif); } + + // Méthode ecrireEtatActif + public void ecrireEtatActif(Boolean etatActif) { pEtatActif = etatActif; } + + // Méthode lireRetard + public long lireRetard() { return (pRetard); } + + // Méthode ecrireRetard + public void ecrireRetard(long retard) { pRetard = retard; } + + // Méthode lireDuree + public long lireDuree() { return (pDuree); } + + // Méthode ecrireDuree + public void ecrireDuree(long duree) { pDuree = duree; } +} diff --git a/app/src/main/res/drawable/ic_arrow_down.png b/app/src/main/res/drawable/ic_arrow_down.png new file mode 100644 index 0000000..acab7c9 Binary files /dev/null and b/app/src/main/res/drawable/ic_arrow_down.png differ diff --git a/app/src/main/res/drawable/ic_arrow_up.png b/app/src/main/res/drawable/ic_arrow_up.png new file mode 100644 index 0000000..f021e50 Binary files /dev/null and b/app/src/main/res/drawable/ic_arrow_up.png differ diff --git a/app/src/main/res/drawable/ic_checked.png b/app/src/main/res/drawable/ic_checked.png new file mode 100644 index 0000000..db1bc99 Binary files /dev/null and b/app/src/main/res/drawable/ic_checked.png differ diff --git a/app/src/main/res/drawable/ic_roller.png b/app/src/main/res/drawable/ic_roller.png new file mode 100644 index 0000000..578e066 Binary files /dev/null and b/app/src/main/res/drawable/ic_roller.png differ diff --git a/app/src/main/res/drawable/ic_unchecked.png b/app/src/main/res/drawable/ic_unchecked.png new file mode 100644 index 0000000..d232bdb Binary files /dev/null and b/app/src/main/res/drawable/ic_unchecked.png differ diff --git a/app/src/main/res/layout/activity_chronos24h_le_mans.xml b/app/src/main/res/layout/activity_chronos24h_le_mans.xml new file mode 100644 index 0000000..1c984e8 --- /dev/null +++ b/app/src/main/res/layout/activity_chronos24h_le_mans.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_parametres.xml b/app/src/main/res/layout/activity_parametres.xml new file mode 100644 index 0000000..4a1a108 --- /dev/null +++ b/app/src/main/res/layout/activity_parametres.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/grid_view_resultat.xml b/app/src/main/res/layout/grid_view_resultat.xml new file mode 100644 index 0000000..4327144 --- /dev/null +++ b/app/src/main/res/layout/grid_view_resultat.xml @@ -0,0 +1,48 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/list_view_coureur.xml b/app/src/main/res/layout/list_view_coureur.xml new file mode 100644 index 0000000..00d467b --- /dev/null +++ b/app/src/main/res/layout/list_view_coureur.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/spinner_coureur.xml b/app/src/main/res/layout/spinner_coureur.xml new file mode 100644 index 0000000..e168f51 --- /dev/null +++ b/app/src/main/res/layout/spinner_coureur.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/tab_course.xml b/app/src/main/res/layout/tab_course.xml new file mode 100644 index 0000000..a63a41d --- /dev/null +++ b/app/src/main/res/layout/tab_course.xml @@ -0,0 +1,146 @@ + + +