generated from Grigo/AndroidTemplate
Created ship vectors (not added yet)
Created menu Created udp support Created DockWidgets for compass and SOG/COG
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user