From e9b2c02134adcba68db54d4ff32c9f96996094c9 Mon Sep 17 00:00:00 2001
From: t22couch <thibaud.couchet@imt-atlantique.net>
Date: Tue, 25 Mar 2025 16:40:55 +0100
Subject: [PATCH] UE TERMINEE MANQUE COMMENTAIRES

---
 app/src/main/AndroidManifest.xml              |   4 +
 .../myfirstapplication/AddMarkerActivity.java | 139 ++++++++++++++++++
 .../myfirstapplication/MapsFragment.java      |  90 ++++++++----
 .../MarkerDetailActivity.java                 |  30 ++++
 .../myfirstapplication/MyMarkerData.java      |  49 ++++++
 .../main/res/layout/activity_add_marker.xml   |  34 +++++
 .../res/layout/activity_marker_detail.xml     |  24 +++
 7 files changed, 344 insertions(+), 26 deletions(-)
 create mode 100644 app/src/main/java/fr/imt_atlantique/myfirstapplication/AddMarkerActivity.java
 create mode 100644 app/src/main/java/fr/imt_atlantique/myfirstapplication/MarkerDetailActivity.java
 create mode 100644 app/src/main/java/fr/imt_atlantique/myfirstapplication/MyMarkerData.java
 create mode 100644 app/src/main/res/layout/activity_add_marker.xml
 create mode 100644 app/src/main/res/layout/activity_marker_detail.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e610a7c..2d57f52 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -9,6 +9,8 @@
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-feature android:name="android.hardware.camera" android:required="false"/>
 
     <queries>
         <intent>
@@ -56,6 +58,8 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".AddMarkerActivity" />
+        <activity android:name=".MarkerDetailActivity" />
     </application>
 
 </manifest>
\ No newline at end of file
diff --git a/app/src/main/java/fr/imt_atlantique/myfirstapplication/AddMarkerActivity.java b/app/src/main/java/fr/imt_atlantique/myfirstapplication/AddMarkerActivity.java
new file mode 100644
index 0000000..9912614
--- /dev/null
+++ b/app/src/main/java/fr/imt_atlantique/myfirstapplication/AddMarkerActivity.java
@@ -0,0 +1,139 @@
+package fr.imt_atlantique.myfirstapplication;
+
+import android.app.Activity;
+import android.Manifest;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import java.io.ByteArrayOutputStream;
+
+public class AddMarkerActivity extends AppCompatActivity {
+
+    private static final int REQUEST_IMAGE_CAPTURE = 1;
+    private static final int REQUEST_CAMERA_PERMISSION = 2;
+    private static final String KEY_TITLE = "key_title";
+    private static final String KEY_IMAGE = "key_image";
+    private Bitmap markerImage = null;
+    private double lat, lng;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_add_marker);
+
+        EditText titleInput = findViewById(R.id.markerTitleInput);
+        ImageView photoPreview = findViewById(R.id.markerPhotoPreview);
+        Button takePhotoBtn = findViewById(R.id.takePhotoBtn);
+        Button validateBtn = findViewById(R.id.validateBtn);
+
+        lat = getIntent().getDoubleExtra("lat", 0);
+        lng = getIntent().getDoubleExtra("lng", 0);
+
+        takePhotoBtn.setOnClickListener(v -> {
+            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
+                    != PackageManager.PERMISSION_GRANTED) {
+                ActivityCompat.requestPermissions(this,
+                        new String[]{Manifest.permission.CAMERA},
+                        REQUEST_CAMERA_PERMISSION);
+            } else {
+                launchCamera();
+            }
+        });
+
+        validateBtn.setOnClickListener(v -> {
+            Intent result = new Intent();
+            result.putExtra("title", titleInput.getText().toString());
+            result.putExtra("lat", lat);
+            result.putExtra("lng", lng);
+
+            if (markerImage != null) {
+                ByteArrayOutputStream stream = new ByteArrayOutputStream();
+                markerImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
+                result.putExtra("image", stream.toByteArray());
+            }
+
+            setResult(Activity.RESULT_OK, result);
+            finish();
+        });
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK && data != null) {
+            markerImage = (Bitmap) data.getExtras().get("data");
+
+            ImageView preview = findViewById(R.id.markerPhotoPreview);
+            preview.setImageBitmap(markerImage);
+        }
+    }
+
+    private void launchCamera() {
+        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
+            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+                                           @NonNull int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+        if (requestCode == REQUEST_CAMERA_PERMISSION) {
+            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                launchCamera();
+            } else {
+                Toast.makeText(this, "Permission caméra refusée", Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        EditText titleInput = findViewById(R.id.markerTitleInput);
+        outState.putString(KEY_TITLE, titleInput.getText().toString());
+
+        if (markerImage != null) {
+            ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            markerImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
+            outState.putByteArray(KEY_IMAGE, stream.toByteArray());
+        }
+    }
+
+    @Override
+    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+
+        EditText titleInput = findViewById(R.id.markerTitleInput);
+        ImageView photoPreview = findViewById(R.id.markerPhotoPreview);
+
+        String restoredTitle = savedInstanceState.getString(KEY_TITLE);
+        if (restoredTitle != null) {
+            titleInput.setText(restoredTitle);
+        }
+
+        byte[] imageBytes = savedInstanceState.getByteArray(KEY_IMAGE);
+        if (imageBytes != null) {
+            markerImage = android.graphics.BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
+            photoPreview.setImageBitmap(markerImage);
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/imt_atlantique/myfirstapplication/MapsFragment.java b/app/src/main/java/fr/imt_atlantique/myfirstapplication/MapsFragment.java
index 2db2838..c6ae4b0 100644
--- a/app/src/main/java/fr/imt_atlantique/myfirstapplication/MapsFragment.java
+++ b/app/src/main/java/fr/imt_atlantique/myfirstapplication/MapsFragment.java
@@ -1,5 +1,7 @@
 package fr.imt_atlantique.myfirstapplication;
 
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.widget.Toolbar;
@@ -8,8 +10,12 @@ import androidx.core.content.ContextCompat;
 import androidx.fragment.app.Fragment;
 
 import android.Manifest;
+import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -21,6 +27,7 @@ import com.google.android.gms.maps.CameraUpdateFactory;
 import com.google.android.gms.maps.GoogleMap;
 import com.google.android.gms.maps.OnMapReadyCallback;
 import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
 import com.google.android.gms.maps.model.CameraPosition;
 import com.google.android.gms.maps.model.LatLng;
 import com.google.android.gms.maps.model.MarkerOptions;
@@ -31,7 +38,7 @@ public class MapsFragment extends Fragment {
 
     private Toolbar toolbar;
     private GoogleMap mMap;
-    private final ArrayList<LatLng> markerPositions = new ArrayList<>();
+    private final ArrayList<MyMarkerData> markerDataList = new ArrayList<>();
 
     public MapsFragment() {
         // Required empty public constructor
@@ -41,6 +48,28 @@ public class MapsFragment extends Fragment {
         return new MapsFragment();
     }
 
+    private final ActivityResultLauncher<Intent> addMarkerLauncher =
+            registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+                if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
+                    Intent data = result.getData();
+                    double lat = data.getDoubleExtra("lat", 0);
+                    double lng = data.getDoubleExtra("lng", 0);
+                    String title = data.getStringExtra("title");
+                    byte[] imageBytes = data.getByteArrayExtra("image");
+
+                    LatLng position = new LatLng(lat, lng);
+                    MyMarkerData markerData = new MyMarkerData(position, title, imageBytes);
+                    markerDataList.add(markerData);
+
+                    MarkerOptions markerOptions = new MarkerOptions().position(position).title(title);
+                    if (imageBytes != null) {
+                        Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
+                        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
+                    }
+                    mMap.addMarker(markerOptions);
+                }
+            });
+
     private OnMapReadyCallback callback = new OnMapReadyCallback() {
 
         /**
@@ -56,9 +85,17 @@ public class MapsFragment extends Fragment {
         public void onMapReady(GoogleMap googleMap) {
             mMap = googleMap;
             // Redessine les anciens marqueurs si existants
-            for (LatLng position : markerPositions) {
-                googleMap.addMarker(new MarkerOptions().position(position)
-                        .title("Lat: " + position.latitude + ", Lng: " + position.longitude));
+            for (MyMarkerData data : markerDataList) {
+                MarkerOptions markerOptions = new MarkerOptions()
+                        .position(data.position)
+                        .title(data.title);
+
+                if (data.imageBytes != null) {
+                    Bitmap bitmap = BitmapFactory.decodeByteArray(data.imageBytes, 0, data.imageBytes.length);
+                    markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
+                }
+
+                googleMap.addMarker(markerOptions);
             }
             // We check for the application "Call permission"
             if (ContextCompat.checkSelfPermission(requireContext(),
@@ -81,26 +118,27 @@ public class MapsFragment extends Fragment {
                         Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show();
                     }
                 });
-                googleMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
-                    @Override
-                    public void onMapLongClick(LatLng latLng) {
-                        double latitude = latLng.latitude;
-                        double longitude = latLng.longitude;
-
-                        String title = "Lat: " + latitude + ", Lng: " + longitude;
-
-                        // Crée le marker
-                        MarkerOptions markerOptions = new MarkerOptions()
-                                .position(latLng)
-                                .title(title);
-
-                        // Ajoute le marker à la carte
-                        googleMap.addMarker(markerOptions);
-                        markerPositions.add(latLng);
-
-                        // Affiche un toast
-                        Toast.makeText(requireContext(), "Marqueur ajouté à " + title, Toast.LENGTH_SHORT).show();
+                googleMap.setOnMapLongClickListener(latLng -> {
+                    Intent intent = new Intent(requireContext(), AddMarkerActivity.class);
+                    intent.putExtra("lat", latLng.latitude);
+                    intent.putExtra("lng", latLng.longitude);
+                    addMarkerLauncher.launch(intent);
+                });
+                googleMap.setOnMarkerClickListener(marker -> {
+                    LatLng clickedPosition = marker.getPosition();
+
+                    // Retrouver le bon MyMarkerData
+                    for (MyMarkerData data : markerDataList) {
+                        if (data.position.equals(clickedPosition)) {
+                            Intent intent = new Intent(requireContext(), MarkerDetailActivity.class);
+                            intent.putExtra("title", data.title);
+                            intent.putExtra("image", data.imageBytes);
+                            startActivity(intent);
+                            return true; // on consomme l'événement
+                        }
                     }
+
+                    return false; // comportement par défaut sinon
                 });
             } catch (SecurityException e) {
                 Log.e("MapsFragment", "Error while enabling location", e);
@@ -125,9 +163,9 @@ public class MapsFragment extends Fragment {
                              @Nullable ViewGroup container,
                              @Nullable Bundle savedInstanceState) {
         if (savedInstanceState != null) {
-            ArrayList<LatLng> savedMarkers = savedInstanceState.getParcelableArrayList("markers");
+            ArrayList<MyMarkerData> savedMarkers = savedInstanceState.getParcelableArrayList("markers");
             if (savedMarkers != null) {
-                markerPositions.addAll(savedMarkers);
+                markerDataList.addAll(savedMarkers);
             }
         }
         return inflater.inflate(R.layout.fragment_maps, container, false);
@@ -164,6 +202,6 @@ public class MapsFragment extends Fragment {
     @Override
     public void onSaveInstanceState(@NonNull Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putParcelableArrayList("markers", markerPositions);
+        outState.putParcelableArrayList("markers", markerDataList);
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/fr/imt_atlantique/myfirstapplication/MarkerDetailActivity.java b/app/src/main/java/fr/imt_atlantique/myfirstapplication/MarkerDetailActivity.java
new file mode 100644
index 0000000..5ec8a7e
--- /dev/null
+++ b/app/src/main/java/fr/imt_atlantique/myfirstapplication/MarkerDetailActivity.java
@@ -0,0 +1,30 @@
+package fr.imt_atlantique.myfirstapplication;
+
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+public class MarkerDetailActivity extends AppCompatActivity {
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_marker_detail);
+
+        TextView titleView = findViewById(R.id.markerDetailTitle);
+        ImageView imageView = findViewById(R.id.markerDetailImage);
+
+        String title = getIntent().getStringExtra("title");
+        byte[] imageBytes = getIntent().getByteArrayExtra("image");
+
+        titleView.setText(title);
+
+        if (imageBytes != null) {
+            imageView.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/imt_atlantique/myfirstapplication/MyMarkerData.java b/app/src/main/java/fr/imt_atlantique/myfirstapplication/MyMarkerData.java
new file mode 100644
index 0000000..11ce1a8
--- /dev/null
+++ b/app/src/main/java/fr/imt_atlantique/myfirstapplication/MyMarkerData.java
@@ -0,0 +1,49 @@
+package fr.imt_atlantique.myfirstapplication;
+
+import android.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.gms.maps.model.LatLng;
+
+public class MyMarkerData implements Parcelable {
+    public LatLng position;
+    public String title;
+    public byte[] imageBytes; // L’image compressée
+
+    public MyMarkerData(LatLng position, String title, byte[] imageBytes) {
+        this.position = position;
+        this.title = title;
+        this.imageBytes = imageBytes;
+    }
+
+    protected MyMarkerData(Parcel in) {
+        position = in.readParcelable(LatLng.class.getClassLoader());
+        title = in.readString();
+        imageBytes = in.createByteArray();
+    }
+
+    public static final Creator<MyMarkerData> CREATOR = new Creator<MyMarkerData>() {
+        @Override
+        public MyMarkerData createFromParcel(Parcel in) {
+            return new MyMarkerData(in);
+        }
+
+        @Override
+        public MyMarkerData[] newArray(int size) {
+            return new MyMarkerData[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int i) {
+        parcel.writeParcelable(position, i);
+        parcel.writeString(title);
+        parcel.writeByteArray(imageBytes);
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_add_marker.xml b/app/src/main/res/layout/activity_add_marker.xml
new file mode 100644
index 0000000..9470d46
--- /dev/null
+++ b/app/src/main/res/layout/activity_add_marker.xml
@@ -0,0 +1,34 @@
+<?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="wrap_content"
+    android:orientation="vertical"
+    android:padding="24dp">
+
+    <EditText
+        android:id="@+id/markerTitleInput"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="Titre du marqueur" />
+
+    <Button
+        android:id="@+id/takePhotoBtn"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Prendre une photo" />
+
+    <ImageView
+        android:id="@+id/markerPhotoPreview"
+        android:layout_width="match_parent"
+        android:layout_height="200dp"
+        android:scaleType="centerCrop"
+        android:layout_marginTop="8dp"
+        android:background="#DDD" />
+
+    <Button
+        android:id="@+id/validateBtn"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Valider"
+        android:layout_marginTop="16dp" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_marker_detail.xml b/app/src/main/res/layout/activity_marker_detail.xml
new file mode 100644
index 0000000..4617e47
--- /dev/null
+++ b/app/src/main/res/layout/activity_marker_detail.xml
@@ -0,0 +1,24 @@
+<?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:orientation="vertical"
+    android:padding="24dp">
+
+    <TextView
+        android:id="@+id/markerDetailTitle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Titre"
+        android:textSize="24sp"
+        android:textStyle="bold"
+        android:layout_marginBottom="16dp" />
+
+    <ImageView
+        android:id="@+id/markerDetailImage"
+        android:layout_width="match_parent"
+        android:layout_height="300dp"
+        android:scaleType="centerCrop"
+        android:contentDescription="Photo du marqueur" />
+</LinearLayout>
\ No newline at end of file
-- 
GitLab