Daily checkup

This commit is contained in:
2026-05-20 08:49:14 +03:00
parent 2fbeae26a6
commit b22cdd93eb
46 changed files with 5478 additions and 680 deletions
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,2a10,10 0,1 1,-0.01,0zM12,4a8,8 0,1 0,0.01,0z" />
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,6a6,6 0,1 1,-0.01,0zM12,8a4,4 0,1 0,0.01,0z" />
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,12 L20,4 L18,12 L12,12z" />
<path
android:strokeColor="#FFFFFFFF"
android:strokeWidth="1.2"
android:pathData="M12,12 L12,3" />
</vector>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorOnSurface">
<!-- Базовая «волновая» иконка сигнала, перечёркнутая диагональной чертой,
что обозначает потерю связи. Цветовой токен берётся из темы. -->
<path
android:fillColor="@android:color/white"
android:pathData="M2,22h20l-3,-3H5z" />
<path
android:fillColor="@android:color/white"
android:pathData="M21.07,4.93l-1.41,-1.41L4.93,18.66c-0.39,0.39 -0.39,1.02 0,1.41l0.0,0.0c0.39,0.39 1.02,0.39 1.41,0L21.07,6.34C21.46,5.95 21.46,5.32 21.07,4.93z" />
<path
android:fillColor="@android:color/white"
android:pathData="M12,4l-1.5,1.5l1.5,1.5l1.5,-1.5L12,4zM7.5,8.5L9,10l3,-3l-1.5,-1.5L7.5,8.5z" />
</vector>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:endColor="@color/plotter_bezel_dark"
android:startColor="@color/plotter_bezel_light"
android:type="linear" />
</shape>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/plotter_panel_bg" />
<stroke
android:width="1dp"
android:color="@color/plotter_panel_stroke" />
<corners android:radius="4dp" />
</shape>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="@color/plotter_radar_bg" />
<stroke
android:width="3dp"
android:color="@color/plotter_bezel_highlight" />
</shape>
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/radar_plotter_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/plotter_bezel_background"
tools:context=".RadarPlotterActivity">
<!-- Верхняя панель: заголовок + назад -->
<LinearLayout
android:id="@+id/radar_top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="12dp"
android:paddingBottom="4dp">
<ImageButton
android:id="@+id/btn_radar_back"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/button_background"
android:contentDescription="@string/radar_plotter_back"
android:padding="8dp"
android:scaleType="fitCenter"
android:src="@android:drawable/ic_menu_revert" />
<TextView
android:id="@+id/tv_radar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:text="@string/radar_plotter_title"
android:textColor="@color/plotter_text_primary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_radar_range"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/plotter_text_accent"
android:textSize="12sp"
tools:text="5.0 nm" />
</LinearLayout>
<!-- Портрет: PPI сверху, приборы снизу -->
<LinearLayout
android:id="@+id/radar_plotter_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="46dp"
android:layout_marginBottom="4dp"
android:orientation="vertical"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/radar_viewport_frame"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.2"
android:background="@drawable/plotter_radar_viewport_bg"
android:padding="4dp">
<org.maplibre.android.maps.MapView
android:id="@+id/radar_map_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.grigowashere.aismap.view.RadarGraticuleOverlay
android:id="@+id/radar_graticule"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<LinearLayout
android:id="@+id/radar_instruments_panel"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="2dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:id="@+id/plotter_instruments_row"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_weight="0.38"
android:baselineAligned="false"
android:orientation="horizontal">
<com.grigowashere.aismap.view.PlotterHeadingView
android:id="@+id/plotter_heading"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/plotter_panel_background" />
<com.grigowashere.aismap.view.PlotterSpeedometerView
android:id="@+id/plotter_speedometer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:background="@drawable/plotter_panel_background" />
</LinearLayout>
<com.grigowashere.aismap.view.PlotterTargetsTableView
android:id="@+id/plotter_targets_table"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/plotter_panel_background" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/settings_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:padding="16dp">
<LinearLayout
@@ -13,20 +15,19 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🔌 Интерфейсы: UDP и BLE"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="@android:color/black"
android:layout_marginBottom="24dp"
android:gravity="center"
android:layout_marginBottom="24dp" />
android:text="@string/interfaces_title"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface" />
<!-- UDP -->
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="match_parent"
@@ -37,18 +38,17 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📡 UDP"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@android:color/black"
android:layout_marginBottom="12dp" />
android:layout_marginBottom="12dp"
android:text="@string/interfaces_section_udp"
android:textAppearance="?attr/textAppearanceTitleMedium"
android:textColor="?attr/colorOnSurface" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:hint="UDP Порт"
app:helperText="Порт для прослушивания AIS данных">
android:hint="@string/interfaces_udp_port_hint"
app:helperText="@string/interfaces_udp_port_helper">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_udp_port"
@@ -63,20 +63,20 @@
android:id="@+id/switch_udp_enabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Включить UDP слушатель"
android:textSize="16sp"
android:checked="true" />
android:checked="true"
android:text="@string/interfaces_udp_enabled" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- BLE -->
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="match_parent"
@@ -87,33 +87,30 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📶 BLE"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@android:color/black"
android:layout_marginBottom="12dp" />
android:layout_marginBottom="12dp"
android:text="@string/interfaces_section_ble"
android:textAppearance="?attr/textAppearanceTitleMedium"
android:textColor="?attr/colorOnSurface" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_ble_enabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Включить BLE источник NMEA"
android:textSize="16sp"
android:layout_marginBottom="8dp" />
android:layout_marginBottom="8dp"
android:text="@string/interfaces_ble_enabled" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:hint="MAC адрес BLE устройства"
app:helperText="Например: 01:23:45:67:89:AB">
android:hint="@string/interfaces_ble_mac_hint"
app:helperText="@string/interfaces_ble_mac_helper">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_ble_mac"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:text="" />
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
@@ -122,20 +119,20 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_ble_scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Сканировать BLE"
style="@style/Widget.Material3.Button" />
android:text="@string/interfaces_ble_scan" />
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_ble_stop_scan"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Стоп"
android:layout_marginStart="8dp"
style="@style/Widget.Material3.Button.OutlinedButton" />
android:text="@string/interfaces_ble_stop" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
@@ -144,16 +141,33 @@
android:layout_height="200dp"
android:layout_marginTop="8dp" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_ble_battery_enabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/interfaces_ble_battery_enabled" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="4dp"
android:text="@string/interfaces_ble_battery_helper"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- BLE UDP Bridge -->
<!-- BLE UDP Bridge -->
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="match_parent"
@@ -164,25 +178,23 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🔁 BLE UDP Bridge"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@android:color/black"
android:layout_marginBottom="12dp" />
android:layout_marginBottom="12dp"
android:text="@string/interfaces_section_bridge"
android:textAppearance="?attr/textAppearanceTitleMedium"
android:textColor="?attr/colorOnSurface" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_ble_udp_bridge_enabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Включить UDP-bridge (пересылать NMEA)"
android:textSize="16sp"
android:layout_marginBottom="8dp" />
android:layout_marginBottom="8dp"
android:text="@string/interfaces_bridge_enabled" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:hint="UDP Host (назначение)">
android:hint="@string/interfaces_bridge_host_hint">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_ble_udp_host"
@@ -196,8 +208,7 @@
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:hint="UDP Port (назначение)">
android:hint="@string/interfaces_bridge_port_hint">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_ble_udp_port"
@@ -209,29 +220,33 @@
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal"
android:gravity="end">
android:paddingTop="8dp"
android:paddingBottom="8dp">
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_cancel"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Отмена"
android:layout_marginEnd="8dp"
style="@style/Widget.Material3.Button.OutlinedButton" />
android:text="@string/settings_action_cancel" />
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Сохранить"
style="@style/Widget.Material3.Button" />
android:text="@string/settings_action_save" />
</LinearLayout>
</LinearLayout>
</ScrollView>
+84 -24
View File
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_root"
android:layout_width="match_parent"
@@ -13,29 +14,65 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Компас -->
<!-- Баннер потери BLE-связи. Компас привязан ниже — не перекрывает текст. -->
<LinearLayout
android:id="@+id/banner_connection_lost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@color/connection_lost_bg"
android:elevation="8dp"
android:gravity="center"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:paddingEnd="16dp"
android:paddingBottom="10dp"
android:visibility="gone">
<TextView
android:id="@+id/tv_banner_connection_lost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="10dp"
android:gravity="center"
android:text="@string/banner_connection_lost_ble"
android:textAlignment="center"
android:textColor="@color/connection_lost_text"
android:textSize="14sp"
android:textStyle="bold"
app:drawableStartCompat="@drawable/ic_signal_off" />
</LinearLayout>
<!-- Компас. Высоту виджет считает сам через measureDockContentHeightPx —
contentH (~96dp) + системные паддинги (status bar/displayCutout). -->
<com.grigowashere.aismap.view.CompassView
android:id="@+id/compass_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp" />
android:layout_height="wrap_content"
android:layout_below="@id/banner_connection_lost"
android:elevation="2dp" />
<!-- Виджет координат: нижний inset задаётся в MainActivity (system bar) -->
<!-- Виджет координат: contentH считает сам (от размера шрифтов),
к нему MainActivity добавляет bottom inset под нав-бар. -->
<com.grigowashere.aismap.view.CoordinatesDockWidget
android:id="@+id/coordinates_widget"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp"
android:elevation="2dp" />
<!-- Виджет «Опасные цели»: высота зависит от числа целей в зоне опасности
(rowH × N + title + паддинги). Когда целей нет — GONE, карта чистая. -->
<com.grigowashere.aismap.view.DangerTargetsDockWidget
android:id="@+id/danger_targets_widget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/coordinates_widget"
android:elevation="3dp"
android:visibility="gone" />
<!-- Панель управления (после координат в Z-order — не перекрывается снизу) -->
<LinearLayout
android:id="@+id/control_panel"
@@ -60,6 +97,17 @@
android:scaleType="fitCenter"
android:layout_marginBottom="8dp" />
<ImageButton
android:id="@+id/btn_navigator_follow"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/button_background"
android:src="@drawable/sail"
android:contentDescription="@string/main_navigator_button"
android:padding="8dp"
android:scaleType="fitCenter"
android:layout_marginBottom="8dp" />
<ImageButton
android:id="@+id/btn_map_orientation"
android:layout_width="40dp"
@@ -114,52 +162,64 @@
android:scaleType="fitCenter"
android:layout_marginTop="8dp" />
<ImageButton
android:id="@+id/btn_radar_plotter"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/button_background"
android:src="@drawable/ic_radar_plotter"
android:contentDescription="@string/radar_plotter_button"
android:padding="8dp"
android:scaleType="fitCenter"
android:layout_marginTop="8dp" />
<!-- Строки возраста последних сообщений GPS ($) и AIS (!) -->
<!-- Компактный блок статусов: GPS / AIS возраст, BLE RSSI / батарея, FPS.
Уменьшены и шрифт (10sp), и отступы — на телефоне это даёт лишние
~30dp по высоте, не теряя читаемости. -->
<TextView
android:id="@+id/tv_gps_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="GPS: --"
android:textSize="11sp"
android:textColor="@android:color/white"
android:layout_marginTop="8dp"/>
android:textSize="10sp" />
<TextView
android:id="@+id/tv_ais_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="AIS: --"
android:textSize="11sp"
android:textColor="@android:color/white"
android:layout_marginTop="4dp"/>
android:textSize="10sp" />
<TextView
android:id="@+id/tv_ble_rssi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="BLE RSSI: --"
android:textSize="11sp"
android:textColor="@android:color/white"
android:layout_marginTop="4dp"/>
android:textSize="10sp" />
<TextView
android:id="@+id/tv_ble_batt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="BLE Batt: --"
android:textSize="11sp"
android:textColor="@android:color/white"
android:layout_marginTop="2dp"/>
android:textSize="10sp" />
<TextView
android:id="@+id/tv_fps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="FPS: --"
android:textSize="11sp"
android:textColor="@android:color/white"
android:layout_marginTop="4dp"/>
android:textSize="10sp" />
</LinearLayout>
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/radar_plotter_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/plotter_bezel_background"
tools:context=".RadarPlotterActivity">
<!-- Верхняя панель: заголовок + назад -->
<LinearLayout
android:id="@+id/radar_top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="12dp"
android:paddingBottom="4dp">
<ImageButton
android:id="@+id/btn_radar_back"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/button_background"
android:contentDescription="@string/radar_plotter_back"
android:padding="8dp"
android:scaleType="fitCenter"
android:src="@android:drawable/ic_menu_revert" />
<TextView
android:id="@+id/tv_radar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:text="@string/radar_plotter_title"
android:textColor="@color/plotter_text_primary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_radar_range"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/plotter_text_accent"
android:textSize="12sp"
tools:text="5.0 nm" />
</LinearLayout>
<!-- Альбом: PPI слева, приборы справа (портрет — layout-port) -->
<LinearLayout
android:id="@+id/radar_plotter_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="46dp"
android:layout_marginBottom="4dp"
android:orientation="horizontal"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:baselineAligned="false">
<!-- Область PPI / радара -->
<FrameLayout
android:id="@+id/radar_viewport_frame"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.15"
android:background="@drawable/plotter_radar_viewport_bg"
android:padding="4dp">
<org.maplibre.android.maps.MapView
android:id="@+id/radar_map_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.grigowashere.aismap.view.RadarGraticuleOverlay
android:id="@+id/radar_graticule"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<!-- Правая колонка: компас+спидометр в ряд, таблица -->
<LinearLayout
android:id="@+id/radar_instruments_panel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:id="@+id/plotter_instruments_row"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_weight="0.38"
android:baselineAligned="false"
android:orientation="horizontal">
<com.grigowashere.aismap.view.PlotterHeadingView
android:id="@+id/plotter_heading"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/plotter_panel_background" />
<com.grigowashere.aismap.view.PlotterSpeedometerView
android:id="@+id/plotter_speedometer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:background="@drawable/plotter_panel_background" />
</LinearLayout>
<com.grigowashere.aismap.view.PlotterTargetsTableView
android:id="@+id/plotter_targets_table"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/plotter_panel_background" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
File diff suppressed because it is too large Load Diff
@@ -20,7 +20,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="🚢 AIS СУДНО"
android:text="AIS СУДНО"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@android:color/black" />
@@ -51,7 +51,7 @@
android:id="@+id/bottom_sheet_ais_time_ago"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="⏱️ Время назад: --"
android:text="Время назад: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -62,7 +62,7 @@
android:id="@+id/bottom_sheet_ais_mmsi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🆔 MMSI: --"
android:text="MMSI: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -75,7 +75,7 @@
android:id="@+id/bottom_sheet_ais_callsign"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📻 Позывной: --"
android:text="Позывной: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -87,7 +87,7 @@
android:id="@+id/bottom_sheet_ais_imo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🏷️ IMO: --"
android:text="IMO: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -99,7 +99,7 @@
android:id="@+id/bottom_sheet_ais_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🚢 Тип: --"
android:text="Тип: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -111,7 +111,7 @@
android:id="@+id/bottom_sheet_ais_position"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📍 Координаты: --"
android:text="Координаты: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -130,7 +130,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="🧭 COG: --°"
android:text="COG: --°"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -143,7 +143,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="🧭 HDG: --°"
android:text="HDG: --°"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -156,7 +156,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="🔄 ROT: --°/мин"
android:text="ROT: --°/мин"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -170,7 +170,7 @@
android:id="@+id/bottom_sheet_ais_speed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Скорость: -- узлов"
android:text="Скорость: -- узлов"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -182,7 +182,7 @@
android:id="@+id/bottom_sheet_ais_dimensions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📏 Размеры: --"
android:text="Размеры: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -194,7 +194,7 @@
android:id="@+id/bottom_sheet_ais_draft"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🌊 Осадка: -- м"
android:text="Осадка: -- м"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -206,7 +206,7 @@
android:id="@+id/bottom_sheet_ais_destination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🎯 Назначение: --"
android:text="Назначение: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -218,7 +218,7 @@
android:id="@+id/bottom_sheet_ais_eta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ETA: --"
android:text="ETA: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -230,7 +230,7 @@
android:id="@+id/bottom_sheet_ais_nav_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🚦 Статус: --"
android:text="Статус: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -242,7 +242,7 @@
android:id="@+id/bottom_sheet_ais_class"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📋 Класс: --"
android:text="Класс: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -254,7 +254,7 @@
android:id="@+id/bottom_sheet_ais_signal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📶 Сигнал: --"
android:text="Сигнал: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -266,7 +266,7 @@
android:id="@+id/bottom_sheet_ais_distance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="📏 Расстояние: --"
android:text="Расстояние: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -278,7 +278,7 @@
android:id="@+id/bottom_sheet_ais_bearing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🧭 Пеленг: --"
android:text="Пеленг: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
@@ -290,7 +290,7 @@
android:id="@+id/bottom_sheet_ais_last_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🕐 Обновлено: --"
android:text="Обновлено: --"
android:textSize="14sp"
android:textColor="@android:color/black"
android:layout_marginBottom="8dp"
+30 -1
View File
@@ -2,4 +2,33 @@
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
<!-- Кольца дальности вокруг собственного судна.
Альфа-каналы подобраны так, чтобы линии и заливки не перекрывали карту. -->
<color name="range_ring_danger_stroke">#FFD32F2F</color>
<color name="range_ring_danger_fill">#22D32F2F</color>
<color name="range_ring_warning_stroke">#FFFFA000</color>
<color name="range_ring_warning_fill">#1AFFA000</color>
<color name="range_ring_filter_stroke">#FF1976D2</color>
<color name="range_ring_filter_fill">#001976D2</color>
<color name="range_target_warning_halo">#FFFFC107</color>
<!-- Баннер «нет связи» -->
<color name="connection_lost_bg">#E6B71C1C</color>
<color name="connection_lost_text">#FFFFFFFF</color>
<!-- Режим «картплоттер / радар» -->
<color name="plotter_bezel_dark">#FF0A0E12</color>
<color name="plotter_bezel_light">#FF1E2830</color>
<color name="plotter_bezel_highlight">#FF4A5A66</color>
<color name="plotter_panel_bg">#E612181C</color>
<color name="plotter_panel_stroke">#FF3D4F3A</color>
<color name="plotter_radar_bg">#88041008</color>
<color name="plotter_radar_grid">#5533FF66</color>
<color name="plotter_radar_grid_bright">#AA66FF99</color>
<color name="plotter_radar_sweep">#5533FF66</color>
<color name="plotter_text_primary">#FFE8F0E4</color>
<color name="plotter_text_label">#FF7FA88A</color>
<color name="plotter_text_accent">#FFFFB74D</color>
<color name="plotter_target_blip">#FF66FF99</color>
</resources>
+162 -1
View File
@@ -1,3 +1,164 @@
<resources>
<string name="app_name">AISMap</string>
</resources>
<!-- ===== SettingsActivity ===== -->
<string name="settings_title">Настройки AIS Map</string>
<string name="settings_section_interfaces">Интерфейсы</string>
<string name="settings_open_interfaces_hint">Интерфейсы (UDP / BLE)</string>
<string name="settings_open_interfaces_helper">Перейти к настройкам UDP, BLE и UDP-bridge</string>
<string name="settings_open_interfaces_value">Открыть настройки интерфейсов</string>
<string name="settings_open_interfaces_action">Открыть</string>
<string name="settings_section_path">Путь и предсказание</string>
<string name="settings_path_max_points_hint">Максимум точек на судно</string>
<string name="settings_path_max_points_helper">Ограничение размера истории пути</string>
<string name="settings_path_width_hint">Толщина линии пути (px)</string>
<string name="settings_path_color_hint">Цвет пути (#RRGGBB)</string>
<string name="settings_prediction_width_hint">Толщина линии предсказания (px)</string>
<string name="settings_prediction_color_hint">Цвет предсказания (#RRGGBB)</string>
<string name="settings_prediction_horizon_hint">Горизонт предсказания (сек)</string>
<string name="settings_clear_path">Очистить трекер пути</string>
<string name="settings_clear_path_helper">Удаляет все сохранённые точки пути собственного судна</string>
<string name="settings_section_gps_source">Источник координат</string>
<string name="settings_gps_source_hint">Откуда приложение берёт позицию собственного судна.</string>
<string name="settings_gps_source_hub">AIS Hub (BLE)</string>
<string name="settings_gps_source_hub_hint">Позиция и AIS-цели приходят из внешнего AIS Hub по BLE.</string>
<string name="settings_gps_source_android">Android GPS</string>
<string name="settings_gps_source_android_hint">Встроенный GPS устройства (+опциональный внешний NMEA).</string>
<string name="settings_section_range_rings">Зоны вокруг судна</string>
<string name="settings_range_rings_hint">Кольца дальности позволяют выделить опасные цели и ограничить зону отображения.</string>
<string name="settings_range_rings_enabled">Показывать кольца на карте</string>
<string name="settings_range_units">Единицы измерения</string>
<string name="settings_range_unit_nm">Морские мили (nm)</string>
<string name="settings_range_unit_km">Километры (км)</string>
<string name="settings_range_danger_hint">Радиус зоны опасности</string>
<string name="settings_range_danger_helper">Цели в этой зоне отображаются в виджете и считаются опасными</string>
<string name="settings_range_warning_hint">Радиус зоны предупреждения</string>
<string name="settings_range_warning_helper">Цели в этой зоне подсвечиваются на карте</string>
<string name="settings_range_filter_hint">Радиус зоны фильтра</string>
<string name="settings_range_filter_helper">Скрывает цели, расположенные дальше указанного радиуса</string>
<string name="settings_range_filter_enabled">Скрывать цели за пределами зоны фильтра</string>
<string name="settings_range_validation_order">Радиусы должны быть возрастающими: опасность &lt; предупреждение &lt; фильтр</string>
<string name="settings_range_validation_positive">Все радиусы должны быть положительными</string>
<string name="settings_section_advanced_nmea">Расширенные NMEA-источники</string>
<string name="settings_advanced_nmea_hint">Открыть старые настройки Android NMEA / UDP NMEA / режимы данных. Нужны только если вы работаете без AIS Hub.</string>
<string name="settings_advanced_nmea_caption">Выберите источники данных для получения координат и навигационной информации:</string>
<string name="settings_android_nmea_enabled">Android NMEA (GPS API)</string>
<string name="settings_android_nmea_helper">Использовать встроенный GPS Android для получения координат</string>
<string name="settings_udp_nmea_enabled">UDP NMEA</string>
<string name="settings_udp_nmea_helper">Получать NMEA данные через UDP (курс, скорость, спутники)</string>
<string name="settings_data_mode">Режим работы</string>
<string name="settings_data_mode_hybrid">Гибридный режим (рекомендуется)</string>
<string name="settings_data_mode_hybrid_hint">Координаты от Android GPS, остальное от NMEA</string>
<string name="settings_data_mode_nmea">Только NMEA</string>
<string name="settings_data_mode_nmea_hint">Все данные только из NMEA сообщений</string>
<string name="settings_data_mode_android">Только Android GPS</string>
<string name="settings_data_mode_android_hint">Только встроенный GPS Android</string>
<string name="settings_section_stale_data">Устаревание данных AIS</string>
<string name="settings_stale_caption">Настройте время, через которое данные о судах считаются устаревшими:</string>
<string name="settings_stale_warning_hint">Время предупреждения (минуты)</string>
<string name="settings_stale_warning_helper">Суда старше этого времени будут помечены как устаревшие</string>
<string name="settings_stale_remove_hint">Время удаления (минуты)</string>
<string name="settings_stale_remove_helper">Суда старше этого времени будут удалены с карты</string>
<string name="settings_stale_tip">Устаревшие суда отображаются с иконкой потери цели</string>
<string name="settings_section_navigator_camera">Навигаторская камера</string>
<string name="settings_navigator_camera_hint">Карта следует за судном; зум зависит от скорости (0 уз — ближе, макс. скорость — дальше).</string>
<string name="settings_navigator_camera_enabled">Следовать за судном</string>
<string name="settings_navigator_camera_helper">Долгое нажатие на кнопку судна на карте также включает и выключает режим</string>
<string name="settings_navigator_max_speed_hint">Макс. скорость (уз)</string>
<string name="settings_navigator_max_speed_helper">При этой скорости и выше используется минимальный зум</string>
<string name="settings_navigator_zoom_zero_hint">Зум при 0 уз</string>
<string name="settings_navigator_zoom_zero_helper">Максимальное приближение (большее число)</string>
<string name="settings_navigator_zoom_max_hint">Зум при макс. скорости</string>
<string name="settings_navigator_zoom_max_helper">Максимальное отдаление (меньшее число)</string>
<string name="main_navigator_on">Навигатор: следование за судном</string>
<string name="main_navigator_off">Навигатор выключен</string>
<string name="main_navigator_button">Режим навигатора</string>
<string name="settings_section_screen">Управление экраном</string>
<string name="settings_screen_hint">Настройте поведение экрана во время навигации:</string>
<string name="settings_keep_screen_on">Не давать экрану засыпать</string>
<string name="settings_keep_screen_on_helper">Экран будет оставаться включенным во время навигации (рекомендуется для навигатора)</string>
<string name="settings_section_notifications">Уведомления о новых целях AIS</string>
<string name="settings_notifications_hint">Настройте уведомления при обнаружении новых судов:</string>
<string name="settings_vibration">Вибрация</string>
<string name="settings_vibration_helper">Вибрация устройства при обнаружении нового судна</string>
<string name="settings_sound">Звуковое уведомление</string>
<string name="settings_sound_helper">Звуковой сигнал при обнаружении нового судна</string>
<string name="settings_section_debug">Режим отладки</string>
<string name="settings_debug_hint">Включает расширенное логирование и диагностические элементы UI.</string>
<string name="settings_debug_enabled">Включить режим отладки</string>
<string name="settings_section_seamarks">Морские знаки OpenSeaMap</string>
<string name="settings_seamarks_hint">Отображать морские знаки (буи, маяки, навигационные знаки) поверх карты.</string>
<string name="settings_seamarks_enabled">Показывать морские знаки</string>
<string name="settings_seamarks_tip">Источник: OpenSeaMap.org — открытая база данных морских знаков</string>
<string name="settings_action_save">Сохранить</string>
<string name="settings_action_cancel">Отмена</string>
<!-- ===== InterfacesSettingsActivity ===== -->
<string name="interfaces_title">Интерфейсы: UDP и BLE</string>
<string name="interfaces_section_udp">UDP</string>
<string name="interfaces_udp_port_hint">UDP порт</string>
<string name="interfaces_udp_port_helper">Порт для прослушивания AIS данных</string>
<string name="interfaces_udp_enabled">Включить UDP-слушатель</string>
<string name="interfaces_section_ble">BLE</string>
<string name="interfaces_ble_enabled">Включить BLE-источник NMEA</string>
<string name="interfaces_ble_mac_hint">MAC-адрес BLE устройства</string>
<string name="interfaces_ble_mac_helper">Например: 01:23:45:67:89:AB</string>
<string name="interfaces_ble_scan">Сканировать BLE</string>
<string name="interfaces_ble_stop">Стоп</string>
<string name="interfaces_ble_battery_enabled">Читать уровень батареи AIS Hub</string>
<string name="interfaces_ble_battery_helper">Может вызывать запрос сопряжения на некоторых устройствах. Рекомендуется выключить, если периодически появляется системное окно «Сопряжение не выполнено».</string>
<string name="interfaces_section_bridge">BLE → UDP мост</string>
<string name="interfaces_bridge_enabled">Включить UDP-bridge (пересылать NMEA)</string>
<string name="interfaces_bridge_host_hint">UDP host (назначение)</string>
<string name="interfaces_bridge_port_hint">UDP port (назначение)</string>
<!-- ===== MainActivity (баннер связи и виджет опасности) ===== -->
<string name="banner_connection_lost_ble">Потеряна связь с устройством</string>
<string name="banner_pairing_required">BLE требует сопряжения. Проверьте устройство в настройках Bluetooth.</string>
<string name="banner_icon_description">Иконка предупреждения связи</string>
<string name="danger_widget_title">Опасные цели</string>
<string name="danger_widget_empty">В зоне опасности нет целей</string>
<string name="danger_widget_column_target">Цель</string>
<string name="danger_widget_column_bearing">Пел.</string>
<string name="danger_widget_column_distance">Дист.</string>
<!-- ===== Подписи в навигационных виджетах (компас + координаты) ===== -->
<string name="compass_label_heading">КУРС</string>
<string name="compass_label_mag">МАГН.</string>
<string name="coords_label_position">КООРДИНАТЫ</string>
<string name="coords_label_sog">СКОР.</string>
<string name="coords_label_cog">ПУТЬ</string>
<string name="coords_label_acc">ТОЧН.</string>
<string name="coords_value_no_fix">нет фикса</string>
<!-- ===== Режим картплоттера / «тупого радара» ===== -->
<string name="radar_plotter_title">Радар / картплоттер</string>
<string name="radar_plotter_button">Режим радара</string>
<string name="radar_plotter_no_coordinator">Вернитесь на карту — данные AIS недоступны</string>
<string name="radar_plotter_range_label">Дальность</string>
<string name="radar_plotter_sog_label">СКОР.</string>
<string name="radar_plotter_heading_label">КУРС</string>
<string name="radar_plotter_table_title">Ближайшие цели</string>
<string name="radar_plotter_col_name">Цель</string>
<string name="radar_plotter_col_brg">Пел.</string>
<string name="radar_plotter_col_rng">Дист.</string>
<string name="radar_plotter_col_cpa">CPA</string>
<string name="radar_plotter_cpa_na"></string>
<string name="radar_plotter_table_empty">Нет целей в радиусе</string>
<string name="radar_plotter_back">К карте</string>
</resources>
+8
View File
@@ -18,4 +18,12 @@
<item name="android:windowDrawsSystemBarBackgrounds" tools:targetApi="21">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="27">shortEdges</item>
</style>
<!-- Полноэкранный картплоттер: тёмный фон, без action bar -->
<style name="Theme.AISMap.RadarPlotter" parent="Theme.AISMap">
<item name="android:windowFullscreen">true</item>
<item name="android:statusBarColor">@color/plotter_bezel_dark</item>
<item name="android:navigationBarColor">@color/plotter_bezel_dark</item>
<item name="android:windowBackground">@color/plotter_bezel_dark</item>
</style>
</resources>