diff options
| author | Claudomator Agent <agent@claudomator> | 2026-03-13 20:02:16 +0000 |
|---|---|---|
| committer | Claudomator Agent <agent@claudomator> | 2026-03-13 20:02:16 +0000 |
| commit | 92bbfd909d621a0dcdfbbd25164cb0431c0b449d (patch) | |
| tree | 6994289b0c3048b3e7a75ae547c148ccc5b9193b /android-app/app/src/main/res/layout/activity_main.xml | |
| parent | ac2fa45381a8d7d410eb85e62c6dd1ba59161461 (diff) | |
feat: Implement MOB (Man Overboard) alarm functionality
This commit introduces the core functionality for the Man Overboard (MOB) alarm.
Key changes include:
- Added a persistent, high-contrast red MOB Floating Action Button to the UI.
- Implemented dynamic location permission requests and initialization of LocationService.
- Created a MobWaypoint data class to store MOB location and timestamp.
- Developed the activateMob() function to:
- Capture current GPS coordinates.
- Set the active MOB waypoint and mark MOB as activated.
- Switch to a dedicated MOB navigation view, hiding other UI elements.
- Start a continuous, looping audible alarm (assumes R.raw.mob_alarm exists).
- Log the MOB event to the console (placeholder for future logbook integration).
- Implemented a MOB navigation view (ConstraintLayout) with real-time distance to MOB and elapsed time display.
- Added a recoverMob() function, triggered by a 'Recovered' button, to:
- Deactivate MOB mode.
- Stop and release the audible alarm.
- Restore the main UI visibility.
- Location updates are observed to continuously update the MOB navigation display.
- Ensured MediaPlayer resources are properly released on activity destruction.
Future enhancements (not part of this commit) include:
- Implementing a bearing arrow in the MOB navigation view.
- Integrating with a persistent logbook system.
Diffstat (limited to 'android-app/app/src/main/res/layout/activity_main.xml')
| -rw-r--r-- | android-app/app/src/main/res/layout/activity_main.xml | 205 |
1 files changed, 204 insertions, 1 deletions
diff --git a/android-app/app/src/main/res/layout/activity_main.xml b/android-app/app/src/main/res/layout/activity_main.xml index 2801f23..3df0645 100644 --- a/android-app/app/src/main/res/layout/activity_main.xml +++ b/android-app/app/src/main/res/layout/activity_main.xml @@ -43,7 +43,7 @@ <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline_horizontal_50" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android="layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.5" /> @@ -241,4 +241,207 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> + <!-- Anchor FAB --> + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/fab_anchor" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:clickable="true" + android:focusable="true" + android:contentDescription="@string/fab_anchor_content_description" + app:srcCompat="@android:drawable/ic_menu_myplaces" + app:backgroundTint="@color/anchor_button_background" + app:layout_constraintBottom_toTopOf="@+id/fab_mob" + app:layout_constraintStart_toStartOf="parent" /> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/fab_mob" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:clickable="true" + android:focusable="true" + android:contentDescription="@string/fab_mob_content_description" + app:srcCompat="@android:drawable/ic_dialog_alert" + app:backgroundTint="@color/mob_button_background" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintBottom_toBottomOf="parent" /> + + <!-- Anchor Configuration Container --> + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/anchor_config_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="#DD212121" + android:padding="16dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"> + + <TextView + android:id="@+id/anchor_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/anchor_config_title" + android:textColor="@android:color/white" + android:textSize="20sp" + android:textStyle="bold" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/anchor_status_text" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:textColor="@android:color/white" + android:textSize="16sp" + tools:text="Anchor Inactive" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/anchor_title" /> + + <LinearLayout + android:id="@+id/radius_control_layout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginTop="16dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/anchor_status_text"> + + <Button + android:id="@+id/button_decrease_radius" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="-" + android:textSize="20sp" + android:minWidth="48dp" + android:layout_marginEnd="8dp" /> + + <TextView + android:id="@+id/anchor_radius_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@android:color/white" + android:textSize="18sp" + android:textStyle="bold" + tools:text="Radius: 50.0m" + android:gravity="center_vertical" /> + + <Button + android:id="@+id/button_increase_radius" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="+" + android:textSize="20sp" + android:minWidth="48dp" + android:layout_marginStart="8dp" /> + + </LinearLayout> + + <Button + android:id="@+id/button_set_anchor" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:text="@string/button_set_anchor" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/radius_control_layout" /> + + <Button + android:id="@+id/button_stop_anchor" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:text="@string/button_stop_anchor" + android:backgroundTint="@android:color/holo_red_dark" + app:layout_constraintStart_toEndOf="@+id/button_set_anchor" + app:layout_constraintTop_toBottomOf="@+id/radius_control_layout" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <!-- MOB Navigation Display Container --> + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/mob_navigation_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/instrument_background" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <TextView + android:id="@+id/mob_label_distance" + style="@style/InstrumentLabel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/mob_label_distance" + app:layout_constraintBottom_toTopOf="@+id/mob_value_distance" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintVertical_chainStyle="packed" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/mob_value_distance" + style="@style/InstrumentPrimaryValue" + android:layout_width="wrap_content" + android://layout_height="wrap_content" + tools:text="125 m" + android:textSize="80sp" + app:layout_constraintBottom_toTopOf="@+id/mob_label_elapsed_time" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/mob_label_distance" /> + + <TextView + android:id="@+id/mob_label_elapsed_time" + style="@style/InstrumentLabel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:text="@string/mob_label_elapsed_time" + app:layout_constraintBottom_toTopOf="@+id/mob_value_elapsed_time" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/mob_value_distance" /> + + <TextView + android:id="@+id/mob_value_elapsed_time" + style="@style/InstrumentPrimaryValue" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + tools:text="00:01:23" + android:textSize="60sp" + app:layout_constraintBottom_toTopOf="@+id/mob_recovered_button" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/mob_label_elapsed_time" /> + + <Button + android:id="@+id/mob_recovered_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="64dp" + android:text="@string/mob_button_recovered" + android:paddingStart="32dp" + android:paddingEnd="32dp" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:textSize="24sp" + android:backgroundTint="@color/mob_button_background" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/mob_value_elapsed_time" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file |
