package com.grigowashere.aismap; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.widget.Button; import android.widget.EditText; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.Toast; import com.google.android.material.switchmaterial.SwitchMaterial; import androidx.appcompat.app.AppCompatActivity; import com.grigowashere.aismap.utils.SettingsManager; /** * Экран настроек приложения */ public class SettingsActivity extends AppCompatActivity { private static final String TAG = "SettingsActivity"; private SettingsManager settingsManager; // UI элементы private EditText etUDPPort; private SwitchMaterial switchUDPEnabled; private SwitchMaterial switchAndroidNMEAEnabled; private SwitchMaterial switchUDPNMEAEnabled; private RadioGroup radioGroupDataMode; private RadioButton radioHybridMode; private RadioButton radioNMEAOnly; private RadioButton radioAndroidOnly; private Button btnCancel; private Button btnSave; // Состояние настроек до изменений private int originalUDPPort; private boolean originalUDPEnabled; private boolean originalAndroidNMEAEnabled; private boolean originalUDPNMEAEnabled; private String originalDataMode; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); // Инициализируем менеджер настроек settingsManager = new SettingsManager(this); // Инициализируем UI элементы initializeViews(); // Загружаем текущие настройки loadCurrentSettings(); // Сохраняем оригинальные значения saveOriginalSettings(); // Настраиваем обработчики событий setupEventHandlers(); Log.i(TAG, "SettingsActivity создан"); } /** * Инициализирует UI элементы */ private void initializeViews() { etUDPPort = findViewById(R.id.et_udp_port); switchUDPEnabled = findViewById(R.id.switch_udp_enabled); switchAndroidNMEAEnabled = findViewById(R.id.switch_android_nmea_enabled); switchUDPNMEAEnabled = findViewById(R.id.switch_udp_nmea_enabled); radioGroupDataMode = findViewById(R.id.radio_group_data_mode); radioHybridMode = findViewById(R.id.radio_hybrid_mode); radioNMEAOnly = findViewById(R.id.radio_nmea_only); radioAndroidOnly = findViewById(R.id.radio_android_only); btnCancel = findViewById(R.id.btn_cancel); btnSave = findViewById(R.id.btn_save); } /** * Загружает текущие настройки в UI */ private void loadCurrentSettings() { // UDP настройки etUDPPort.setText(String.valueOf(settingsManager.getUDPPort())); switchUDPEnabled.setChecked(settingsManager.isUDPEnabled()); // NMEA настройки switchAndroidNMEAEnabled.setChecked(settingsManager.isAndroidNMEAEnabled()); switchUDPNMEAEnabled.setChecked(settingsManager.isUDPNMEAEnabled()); // Режим данных String dataMode = settingsManager.getDataMode(); switch (dataMode) { case SettingsManager.DATA_MODE_HYBRID: radioHybridMode.setChecked(true); break; case SettingsManager.DATA_MODE_NMEA_ONLY: radioNMEAOnly.setChecked(true); break; case SettingsManager.DATA_MODE_ANDROID_ONLY: radioAndroidOnly.setChecked(true); break; } Log.i(TAG, "Настройки загружены в UI"); } /** * Сохраняет оригинальные значения настроек */ private void saveOriginalSettings() { originalUDPPort = settingsManager.getUDPPort(); originalUDPEnabled = settingsManager.isUDPEnabled(); originalAndroidNMEAEnabled = settingsManager.isAndroidNMEAEnabled(); originalUDPNMEAEnabled = settingsManager.isUDPNMEAEnabled(); originalDataMode = settingsManager.getDataMode(); Log.i(TAG, "Оригинальные настройки сохранены"); } /** * Настраивает обработчики событий */ private void setupEventHandlers() { // Кнопка отмены btnCancel.setOnClickListener(v -> { Log.i(TAG, "Нажата кнопка отмены"); finish(); }); // Кнопка сохранения btnSave.setOnClickListener(v -> { Log.i(TAG, "Нажата кнопка сохранения"); saveSettings(); }); // Обработчик изменения режима данных radioGroupDataMode.setOnCheckedChangeListener((group, checkedId) -> { updateDataModeDescription(); }); // Обработчики переключателей для валидации switchAndroidNMEAEnabled.setOnCheckedChangeListener((buttonView, isChecked) -> { validateDataModeSettings(); }); switchUDPNMEAEnabled.setOnCheckedChangeListener((buttonView, isChecked) -> { validateDataModeSettings(); }); } /** * Обновляет описание режима данных */ private void updateDataModeDescription() { // Здесь можно добавить динамическое обновление описаний // в зависимости от выбранного режима } /** * Валидирует настройки режима данных */ private void validateDataModeSettings() { boolean androidNMEA = switchAndroidNMEAEnabled.isChecked(); boolean udpNMEA = switchUDPNMEAEnabled.isChecked(); // Если оба источника отключены, показываем предупреждение if (!androidNMEA && !udpNMEA) { Toast.makeText(this, "Внимание: Все источники данных отключены!", Toast.LENGTH_LONG).show(); } // Если выбран режим "только NMEA", но UDP NMEA отключен if (radioNMEAOnly.isChecked() && !udpNMEA) { Toast.makeText(this, "Для режима 'Только NMEA' необходимо включить UDP NMEA", Toast.LENGTH_LONG).show(); } // Если выбран режим "только Android", но Android NMEA отключен if (radioAndroidOnly.isChecked() && !androidNMEA) { Toast.makeText(this, "Для режима 'Только Android GPS' необходимо включить Android NMEA", Toast.LENGTH_LONG).show(); } } /** * Сохраняет настройки */ private void saveSettings() { try { // Валидируем UDP порт String portText = etUDPPort.getText().toString().trim(); if (portText.isEmpty()) { Toast.makeText(this, "Порт не может быть пустым", Toast.LENGTH_SHORT).show(); return; } int udpPort; try { udpPort = Integer.parseInt(portText); if (udpPort < 1 || udpPort > 65535) { Toast.makeText(this, "Порт должен быть от 1 до 65535", Toast.LENGTH_SHORT).show(); return; } } catch (NumberFormatException e) { Toast.makeText(this, "Некорректный формат порта", Toast.LENGTH_SHORT).show(); return; } // Получаем выбранный режим данных String dataMode = getSelectedDataMode(); // Валидируем режим данных if (!validateDataMode(dataMode)) { return; } // Сохраняем настройки settingsManager.setUDPPort(udpPort); settingsManager.setUDPEnabled(switchUDPEnabled.isChecked()); settingsManager.setAndroidNMEAEnabled(switchAndroidNMEAEnabled.isChecked()); settingsManager.setUDPNMEAEnabled(switchUDPNMEAEnabled.isChecked()); settingsManager.setDataMode(dataMode); Log.i(TAG, "Настройки сохранены: " + settingsManager.getSettingsSummary()); // Проверяем, нужно ли уведомить MainActivity об изменениях boolean needsRestart = checkIfRestartNeeded(); // Возвращаем результат Intent resultIntent = new Intent(); resultIntent.putExtra("settings_changed", true); resultIntent.putExtra("needs_restart", needsRestart); resultIntent.putExtra("udp_port", udpPort); resultIntent.putExtra("udp_enabled", switchUDPEnabled.isChecked()); resultIntent.putExtra("android_nmea_enabled", switchAndroidNMEAEnabled.isChecked()); resultIntent.putExtra("udp_nmea_enabled", switchUDPNMEAEnabled.isChecked()); resultIntent.putExtra("data_mode", dataMode); setResult(RESULT_OK, resultIntent); Toast.makeText(this, "Настройки сохранены", Toast.LENGTH_SHORT).show(); finish(); } catch (Exception e) { Log.e(TAG, "Ошибка при сохранении настроек: " + e.getMessage(), e); Toast.makeText(this, "Ошибка при сохранении настроек", Toast.LENGTH_SHORT).show(); } } /** * Получает выбранный режим данных */ private String getSelectedDataMode() { int checkedId = radioGroupDataMode.getCheckedRadioButtonId(); if (checkedId == R.id.radio_hybrid_mode) { return SettingsManager.DATA_MODE_HYBRID; } else if (checkedId == R.id.radio_nmea_only) { return SettingsManager.DATA_MODE_NMEA_ONLY; } else if (checkedId == R.id.radio_android_only) { return SettingsManager.DATA_MODE_ANDROID_ONLY; } else { return SettingsManager.DATA_MODE_HYBRID; // По умолчанию } } /** * Валидирует режим данных */ private boolean validateDataMode(String dataMode) { boolean androidNMEA = switchAndroidNMEAEnabled.isChecked(); boolean udpNMEA = switchUDPNMEAEnabled.isChecked(); switch (dataMode) { case SettingsManager.DATA_MODE_HYBRID: if (!androidNMEA && !udpNMEA) { Toast.makeText(this, "Для гибридного режима необходимо включить хотя бы один источник данных", Toast.LENGTH_LONG).show(); return false; } break; case SettingsManager.DATA_MODE_NMEA_ONLY: if (!udpNMEA) { Toast.makeText(this, "Для режима 'Только NMEA' необходимо включить UDP NMEA", Toast.LENGTH_LONG).show(); return false; } break; case SettingsManager.DATA_MODE_ANDROID_ONLY: if (!androidNMEA) { Toast.makeText(this, "Для режима 'Только Android GPS' необходимо включить Android NMEA", Toast.LENGTH_LONG).show(); return false; } break; } return true; } /** * Проверяет, нужно ли перезапустить сервисы */ private boolean checkIfRestartNeeded() { return settingsManager.shouldRestartUDP(originalUDPPort, originalUDPEnabled) || settingsManager.shouldRestartNMEA(originalAndroidNMEAEnabled, originalUDPNMEAEnabled, originalDataMode); } @Override public void onBackPressed() { Log.i(TAG, "Нажата кнопка назад"); finish(); } }