diff --git a/app/build.gradle b/app/build.gradle index 014e853b7b23598719cac6b37bd550c0b164c69d..ae6bebb9585400eb46fd151853e71bdb59891294 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,6 +30,7 @@ android { dependencies { + implementation 'com.google.code.gson:gson:2.10.1' implementation libs.appcompat implementation libs.material implementation libs.activity diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 11b90b23b084f5308535647bdacc8a66bf95dca2..9f95c9a490fe3c2879374579718e7084ed22c68e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,7 +22,7 @@ </intent-filter> </activity> <activity - android:name=".CreateActivity" + android:name=".ModeleActivity" android:exported="false"/> <activity android:name=".OpenActivity" diff --git a/app/src/main/java/fr/ul/projet/MainActivity.java b/app/src/main/java/fr/ul/projet/MainActivity.java index 572c8d4e1d929fe742d3b7bc8646df8423953d4e..1f09ad5fc0cb36017f8631e881f0c53d69034f78 100644 --- a/app/src/main/java/fr/ul/projet/MainActivity.java +++ b/app/src/main/java/fr/ul/projet/MainActivity.java @@ -7,7 +7,6 @@ import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.OpenableColumns; -import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.Toast; @@ -23,14 +22,12 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; -import androidx.lifecycle.ViewModelProvider; import fr.ul.projet.modele.Modele; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private ActivityResultLauncher<Intent> launcher; - private static final int PICK_FILE_REQUEST = 1; @Override protected void onCreate(Bundle savedInstanceState) { @@ -51,7 +48,21 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result){ - int resCode = result.getResultCode(); // Code retourné par l'activité + if (result.getResultCode() == MainActivity.RESULT_OK && result.getData() != null){ + Uri fileUri = result.getData().getData(); + if (fileUri != null){ + Modele modele = new Modele().chargerModele(MainActivity.this, fileUri); + + if (modele != null){ + Intent intent = new Intent(MainActivity.this, ModeleActivity.class); + intent.putExtra("modele", modele); + launcher.launch(intent); + } else{ + Toast.makeText(MainActivity.this, "Impossible de charger le modèle", Toast.LENGTH_LONG).show(); + } + } + } + } } @@ -79,7 +90,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe public void onClick(DialogInterface dialog, int which){ String userInput = input.getText().toString(); Modele modele = new Modele(userInput); - Intent intent = new Intent(MainActivity.this, CreateActivity.class); + Intent intent = new Intent(MainActivity.this, ModeleActivity.class); intent.putExtra("modele", modele); launcher.launch(intent); } @@ -119,25 +130,14 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe } private void openFileChooser(){ - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); - startActivityForResult(Intent.createChooser(intent, "Sélectionner un fichier"), PICK_FILE_REQUEST); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data){ - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == PICK_FILE_REQUEST && resultCode == RESULT_OK && data != null){ - Uri fileUri = data.getData(); + intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"application/json"}); + intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); - if (fileUri != null){ - Intent intent = new Intent(MainActivity.this, OpenActivity.class); - intent.putExtra("fichier", getFileName(fileUri)); - launcher.launch(intent); - } - } + launcher.launch(Intent.createChooser(intent, "Sélectionner un fichier")); } public String getFileName(Uri uri){ diff --git a/app/src/main/java/fr/ul/projet/CreateActivity.java b/app/src/main/java/fr/ul/projet/ModeleActivity.java similarity index 62% rename from app/src/main/java/fr/ul/projet/CreateActivity.java rename to app/src/main/java/fr/ul/projet/ModeleActivity.java index fc84cffe492504fb0ec658c1b0b139ac8fc0939e..b52c0eae17c4e2eb9e6671b7b90574adc406ce6e 100644 --- a/app/src/main/java/fr/ul/projet/CreateActivity.java +++ b/app/src/main/java/fr/ul/projet/ModeleActivity.java @@ -1,11 +1,17 @@ package fr.ul.projet; +import android.content.ContentValues; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; import android.view.View; import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.activity.result.ActivityResult; @@ -17,12 +23,15 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; -import androidx.lifecycle.ViewModelProvider; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; import fr.ul.projet.modele.Modele; -import fr.ul.projet.modele.Piece; -public class CreateActivity extends AppCompatActivity { +public class ModeleActivity extends AppCompatActivity { private ActivityResultLauncher<Intent> launcher; private Modele modele; @@ -70,7 +79,7 @@ public class CreateActivity extends AppCompatActivity { public void onClick(DialogInterface dialog, int which){ String userInput = input.getText().toString(); modele.ajouterPiece(userInput, "", "", "", ""); - Intent intent = new Intent(CreateActivity.this, PieceActivity.class); + Intent intent = new Intent(ModeleActivity.this, PieceActivity.class); intent.putExtra("modele", modele); launcher.launch(intent); } @@ -87,7 +96,35 @@ public class CreateActivity extends AppCompatActivity { } public void quit(View v){ - Intent res = new Intent(CreateActivity.this, MainActivity.class); + Intent res = new Intent(ModeleActivity.this, MainActivity.class); launcher.launch(res); } + + public void save(View v){ + this.enregistrerModele(this); + } + + public void enregistrerModele(Context context) { + ContentValues values = new ContentValues(); + values.put(MediaStore.MediaColumns.DISPLAY_NAME, this.modele.getFichierJson()); + values.put(MediaStore.MediaColumns.MIME_TYPE, "application/json"); + values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS + "/Modeles"); + + Uri uri = context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values); + + if (uri != null) { + try (OutputStream outputStream = context.getContentResolver().openOutputStream(uri)) { + if (outputStream != null) { + outputStream.write(this.modele.toJson().getBytes()); + outputStream.flush(); + outputStream.close(); + Toast.makeText(context, "Fichier enregistré avec succès : " + this.modele.getFichierJson(), Toast.LENGTH_LONG).show(); + } + } catch (IOException e) { + Toast.makeText(context, "Erreur d'écriture du fichier", Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(context, "Impossible de créer le fichier", Toast.LENGTH_SHORT).show(); + } + } } diff --git a/app/src/main/java/fr/ul/projet/PieceActivity.java b/app/src/main/java/fr/ul/projet/PieceActivity.java index 49cc97ab45e9135d3287779929a0e8d96bff53b5..9aee0755a13ecc1ffedfe24275381c836c49168a 100644 --- a/app/src/main/java/fr/ul/projet/PieceActivity.java +++ b/app/src/main/java/fr/ul/projet/PieceActivity.java @@ -92,7 +92,7 @@ public class PieceActivity extends AppCompatActivity { } public void backToModele(View v){ - Intent res = new Intent(PieceActivity.this, CreateActivity.class); + Intent res = new Intent(PieceActivity.this, ModeleActivity.class); res.putExtra("modele", this.modele); launcher.launch(res); } diff --git a/app/src/main/java/fr/ul/projet/modele/Modele.java b/app/src/main/java/fr/ul/projet/modele/Modele.java index 4973e2a293dc062619332f9ed5df1f1ba3f33f2d..7442bb08186b627e2f86f921d9040437790228ef 100644 --- a/app/src/main/java/fr/ul/projet/modele/Modele.java +++ b/app/src/main/java/fr/ul/projet/modele/Modele.java @@ -1,14 +1,21 @@ package fr.ul.projet.modele; +import android.content.Context; +import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; +import com.google.gson.Gson; + import org.json.JSONObject; +import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.HashMap; import java.util.LinkedList; @@ -38,6 +45,14 @@ public class Modele implements Parcelable{ this.fichierJson = new File("").getAbsolutePath() + "/" + this.getNom() + FabriqueIdentifiant.getInstance().getCptJson() + ".json"; } + public Modele(){ + this.pieceAffichee = false; + this.pieceCourante = null; + this.nom = ""; + this.pieces = new HashMap<Integer, Piece>(); + this.fichierJson = new File("").getAbsolutePath() + "/" + this.getNom() + FabriqueIdentifiant.getInstance().getCptJson() + ".json"; + } + protected Modele(Parcel in){ this.pieceAffichee = in.readByte() != 0; this.fichierJson = in.readString(); @@ -244,6 +259,7 @@ public class Modele implements Parcelable{ } try{ + modeleJson.put("nom", this.nom); modeleJson.put("pièces", pieces); } catch (Exception e){ e.printStackTrace(); @@ -252,31 +268,26 @@ public class Modele implements Parcelable{ return modeleJson.toString(); } - public void enregistrerModele() throws Exception { - PrintWriter flotFiltre; - FileWriter flot; - try { - File file = new File(this.fichierJson); + public Modele chargerModele(Context context, Uri fichier){ + try (InputStream inputStream = context.getContentResolver().openInputStream(fichier); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { - if (file.exists()){ - file.delete(); + StringBuilder jsonBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + jsonBuilder.append(line); } - flot = new FileWriter(file.getAbsoluteFile()); - flotFiltre = new PrintWriter(new BufferedWriter(flot)); - flotFiltre.print(this.toJson()); - flotFiltre.close(); - } catch (IOException e){ - throw new Exception("Impossble d'écrire (" + e + ")"); - } - } + String jsonString = jsonBuilder.toString(); - public void chargerModele() throws Exception{ - try{ - // Charger via json - } catch (Exception e) { - throw new Exception("Impossible de charger le modèle (" + e + ")"); + // Désérialiser le JSON en un objet Modele avec Gson + Gson gson = new Gson(); + return gson.fromJson(jsonString, Modele.class); + + } catch (IOException e) { + e.printStackTrace(); + return null; } } diff --git a/app/src/main/res/layout/activity_create.xml b/app/src/main/res/layout/activity_create.xml index be5a14c399b1c90fb440b318fe420cde642f74b7..0175487ce089bb9f14ba63d142bf2f325674466b 100644 --- a/app/src/main/res/layout/activity_create.xml +++ b/app/src/main/res/layout/activity_create.xml @@ -44,4 +44,17 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.836" /> + + <Button + android:id="@+id/boutonSave" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onClick="save" + android:text="@string/sauvegarder" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.497" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.005" /> </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cbc4a8422f95425fd9fbf94db0ea42e9a0ca3981..e7234d130d55ee80a9d8f302ccc7601d26704b34 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,4 +7,5 @@ <string name="quitter">Retour à l\'accueil</string> <string name="accueil">Retour au modèle</string> <string name="creer_piece">Ajouter un pièce</string> + <string name="sauvegarder">Sauvegarder le modèle</string> </resources> \ No newline at end of file