diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml deleted file mode 100644 index 5a8e5f9cf6dcf38c4e6d5ddfde5866b84c191938..0000000000000000000000000000000000000000 --- a/.idea/deploymentTargetSelector.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="deploymentTargetSelector"> - <selectionStates> - <SelectionState runConfigName="app"> - <option name="selectionMode" value="DROPDOWN" /> - <DropdownSelection timestamp="2024-12-15T17:00:55.472861300Z"> - <Target type="DEFAULT_BOOT"> - <handle> - <DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Prosp\.android\avd\Medium_Phone_API_35.avd" /> - </handle> - </Target> - </DropdownSelection> - <DialogSelection /> - </SelectionState> - </selectionStates> - </component> -</project> \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 44c862e9a4a77e4a0a35926bf7bfcc68c8e02d5a..3cef3fdeb70e696e4bebaa6df4e6485448e1d1b7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.CAMERA" /> - <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" @@ -26,26 +26,32 @@ tools:targetApi="31"> <activity android:name=".MainActivity" - android:exported="true"> + android:exported="true" + android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - <activity android:name=".HomeActivity" /> - <activity android:name=".TutorialActivity" /> + <activity + android:name=".HomeActivity" + android:screenOrientation="portrait" /> + <activity + android:name=".TutorialActivity" + android:screenOrientation="portrait" /> <activity android:name=".PublicActivity" - android:exported="true" /> + android:exported="true" + android:screenOrientation="portrait" /> <meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" /> - + <provider - android:authorities="${applicationId}.fileprovider" android:name="androidx.core.content.FileProvider" + android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java b/app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java index 4efcdceff0b81a9e3bde6b5d2845e071186e5915..cc9d676e7d079d0ef88925d64b2ba7e94f8bc95b 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java +++ b/app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java @@ -32,7 +32,6 @@ public class OverlayDialogFragmentForm extends DialogFragment { private boolean isZoneSelected = false; private String time; - private boolean isTimeSelected = false; private String finalPredictionOutput; @@ -48,6 +47,8 @@ public class OverlayDialogFragmentForm extends DialogFragment { private String surroundingsDescription; + private String unknownSpeciesDescription; + // Linking the Google Forms private final Retrofit retrofit = new Retrofit.Builder().baseUrl("https://docs.google.com/").addConverterFactory(GsonConverterFactory.create()).build(); @@ -73,12 +74,21 @@ public class OverlayDialogFragmentForm extends DialogFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); + Button zoneInfoButton = view.findViewById(R.id.form_zoneInfo); + zoneInfoButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + OverlayDialogFragmentZonage overlayDialogZonage = new OverlayDialogFragmentZonage(); + overlayDialogZonage.show(getParentFragmentManager(), "overlayDialogZonage"); + } + }); + // Select the dropdown menu Spinner zoneSelector = view.findViewById(R.id.zone_selector); // Create the list of options - String[] items = new String[]{"Zone 1\n","Zone 2\n","Zone 3\n","Zone 4\n", + String[] items = new String[]{"Veuillez sélectionner une zone", "Zone 1", "Zone 2", "Zone 3", "Zone 4", "Je ne suis pas dans la rade de Lorient"}; ArrayAdapter<String> adapter = new ArrayAdapter<>(this.getContext(), android.R.layout.simple_spinner_item, items); @@ -91,7 +101,7 @@ public class OverlayDialogFragmentForm extends DialogFragment { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { zoneSelected = parent.getItemAtPosition(position).toString(); - isZoneSelected = true; + if (!zoneSelected.equals(items[0])) isZoneSelected = true; } @Override @@ -110,15 +120,40 @@ public class OverlayDialogFragmentForm extends DialogFragment { @Override public void onTimeChanged(TimePicker timePicker, int i, int i1) { time = timePicker.getHour() + ":" + timePicker.getMinute(); - isTimeSelected = true; } }); // Display the result in the form finalPredictionOutput = PhotoPage.getPredictionOutput(); - TextView predictionDisplay = view.findViewById(R.id.prediction_output); - String predictionText = "Nous avons détecté sur votre photo :\n" + finalPredictionOutput; - predictionDisplay.setText(predictionText); + if (finalPredictionOutput != "nothing") { + TextView predictionDisplay = view.findViewById(R.id.prediction_output); + String predictionText = "Nous avons détecté sur votre photo :\n" + finalPredictionOutput; + predictionDisplay.setText(predictionText); + } else { + EditText unknownSpeciesInput = view.findViewById(R.id.unknown_species_input); + unknownSpeciesInput.setVisibility(EditText.VISIBLE); + + TextView unknownSpecies = view.findViewById(R.id.unknown_species); + unknownSpecies.setVisibility(TextView.VISIBLE); + + unknownSpeciesInput.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + unknownSpeciesDescription="Pas d'espèces fournies."; + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + unknownSpeciesDescription = unknownSpeciesInput.getText().toString(); + } + + @Override + public void afterTextChanged(Editable editable) { + if (unknownSpeciesDescription.isBlank()) unknownSpeciesDescription="Pas d'espèces fournies."; + } + }); + } + String[] numberBySpecies = finalPredictionOutput.split("\n"); @@ -221,35 +256,17 @@ public class OverlayDialogFragmentForm extends DialogFragment { @Override public void onClick(View view) { Call<Void> call = api.sendFormData(becasseauCounter, bernacheCounter, goelandCounter, mouetteCounter, pluvierCounter, cormoranCounter, - foulqueCounter, tadorneCounter, chevalierCounter, "test", zoneSelected.split("\n")[0], surroundingsDescription, "14:30"); + foulqueCounter, tadorneCounter, chevalierCounter, unknownSpeciesDescription, zoneSelected, surroundingsDescription, time); call.enqueue(new Callback<Void>() { @Override public void onResponse(Call<Void> call, Response<Void> response) { try { if (response.isSuccessful()) { - Toast.makeText(getContext(), "Successful", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), "Merci pour votre participation !", Toast.LENGTH_SHORT).show(); + getDialog().dismiss(); } else { - Toast.makeText(getContext(), "Unsuccessful" + response.code() , Toast.LENGTH_SHORT).show(); - - new AlertDialog.Builder(getContext()) - .setTitle("Delete entry") - .setMessage(becasseauCounter + "\n" + bernacheCounter + "\n" + goelandCounter + "\n" + mouetteCounter+ "\n" - + pluvierCounter + "\n" + cormoranCounter + "\n" + foulqueCounter + "\n" - + tadorneCounter + "\n" + chevalierCounter + "\n" + "test" + "\n" + zoneSelected.split("\n")[0] + "\n" + surroundingsDescription + "\n" + "14:30") - - // Specifying a listener allows you to take an action before dismissing the dialog. - // The dialog is automatically dismissed when a dialog button is clicked. - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // Continue with delete operation - } - }) - - // A null listener allows the button to dismiss the dialog and take no further action. - .setNegativeButton(android.R.string.no, null) - .setIcon(android.R.drawable.ic_dialog_alert) - .show(); + if (!isZoneSelected) Toast.makeText(getContext(), "Veuillez sélectionner une zone", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { Toast.makeText(getContext(), "Error: ${e.message}", Toast.LENGTH_SHORT).show(); @@ -259,7 +276,7 @@ public class OverlayDialogFragmentForm extends DialogFragment { @Override public void onFailure(Call<Void> call, Throwable t) { try { - Toast.makeText(getContext(), "Error: ${t.message}", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), "Il vous faut être connecté à Internet pour continuer", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(getContext(), "Error: ${e.message}", Toast.LENGTH_SHORT).show(); } diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentZonage.java b/app/src/main/java/com/example/myapplication/OverlayDialogFragmentZonage.java new file mode 100644 index 0000000000000000000000000000000000000000..0c3d5b0d8ae3ed1d50cb2e98d84ac4417659f832 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/OverlayDialogFragmentZonage.java @@ -0,0 +1,43 @@ +package com.example.myapplication; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; + +public class OverlayDialogFragmentZonage extends DialogFragment { + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + // Inflate the layout for this dialog fragment + return inflater.inflate(R.layout.fragment_overlay_dialog_zonage, container, false); + } + + @Override + public void onStart() { + super.onStart(); + if (getDialog() != null && getDialog().getWindow() != null) { + getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent); // Transparent background + } + Button goBackButton=(Button) this.getView().findViewById(R.id.return_zonage); + + View.OnClickListener listenerGoBackButton=new View.OnClickListener() { + @Override + public void onClick(View view) { + goBack(); + } + }; + + goBackButton.setOnClickListener(listenerGoBackButton); + } + + private void goBack() { + this.getDialog().dismiss(); + } +} diff --git a/app/src/main/java/com/example/myapplication/PhotoPage.java b/app/src/main/java/com/example/myapplication/PhotoPage.java index 0e2cc29fead635866c1fc2ce6ebd30dd8cb004fc..6baa6357614c4f5784f3f11f5a885dec963b8af4 100644 --- a/app/src/main/java/com/example/myapplication/PhotoPage.java +++ b/app/src/main/java/com/example/myapplication/PhotoPage.java @@ -26,6 +26,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import android.widget.Toast; import java.io.IOException; @@ -144,7 +145,6 @@ public class PhotoPage extends Fragment { try { TestModeleTflite testModeleTflite = new TestModeleTflite(this.getContext()); - OutputPredictedImage outputPredictedImage = testModeleTflite.recognizeSpeciesClass(bitmap); Bitmap annotatedImage = outputPredictedImage.getAnnotatedImage(); double height = 1.5 * annotatedImage.getHeight(); @@ -152,12 +152,13 @@ public class PhotoPage extends Fragment { scaledBitmap = Bitmap.createScaledBitmap(annotatedImage, (int) width, (int) height, true); imageView.setImageBitmap(scaledBitmap); //TextView textView = getView().findViewById(R.id.textView2); - predictionOutput=outputPredictedImage.toString(); textPredictionOutput.setText(outputPredictedImage.toString()); } catch (IOException e) { throw new RuntimeException(e); } catch (NoSpeciesRecognizedException e) { + Toast.makeText(getContext(), "L'application n'a pas reconnu d'espèce connue sur votre photo", Toast.LENGTH_SHORT).show(); + predictionOutput="nothing"; textPredictionOutput.setText("Cette espèce n'est pas encore répertoriée."); } } diff --git a/app/src/main/res/drawable/zonage.png b/app/src/main/res/drawable/zonage.png new file mode 100644 index 0000000000000000000000000000000000000000..eebe990528c7087296d5ab6dd628e878d733427a Binary files /dev/null and b/app/src/main/res/drawable/zonage.png differ diff --git a/app/src/main/res/layout/fragment_form.xml b/app/src/main/res/layout/fragment_form.xml index f3ff8307d02a9ec73a2e7ab97bd363eb90073bc6..25e264174bd080ef6a937eca587feb64d95f45eb 100644 --- a/app/src/main/res/layout/fragment_form.xml +++ b/app/src/main/res/layout/fragment_form.xml @@ -76,7 +76,8 @@ android:gravity="center" android:textColor="#333333" android:textSize="18sp" - android:textStyle="bold" /> + android:textStyle="bold" + android:visibility="gone"/> <EditText android:id="@+id/unknown_species_input" @@ -86,7 +87,7 @@ android:hint="@string/unknown_species_question" android:padding="20dp" android:textColor="#000000" - android:editable="false" /> + android:visibility="gone" /> <TextView android:id="@+id/form_date" diff --git a/app/src/main/res/layout/fragment_overlay_dialog_zonage.xml b/app/src/main/res/layout/fragment_overlay_dialog_zonage.xml new file mode 100644 index 0000000000000000000000000000000000000000..8c085b07e47bbf426cc33960bdca9fcaf8f368e5 --- /dev/null +++ b/app/src/main/res/layout/fragment_overlay_dialog_zonage.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginHorizontal="15dp" + android:scaleType="centerInside" + android:src="@drawable/zonage" /> + + <Button + android:id="@+id/return_zonage" + style="@style/ButtonAppearance" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginTop="200dp" + android:paddingLeft="50dp" + android:paddingRight="50dp" + android:text="@string/retour" /> + +</FrameLayout> \ No newline at end of file