package com.grigowashere.aismap.services; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.AudioManager; import android.media.ToneGenerator; import android.os.Build; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorManager; import android.util.Log; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import com.grigowashere.aismap.MainActivity; import com.grigowashere.aismap.R; import com.grigowashere.aismap.utils.SettingsManager; /** * Сервис для обработки уведомлений о новых AIS целях * Поддерживает вибрацию и звуковые уведомления */ public class NotificationService { private static final String TAG = "NotificationService"; private static final String ALERT_CHANNEL_ID = "aismap_alerts"; private static final int SAFETY_NOTIFICATION_ID_BASE = 2000; private Context context; private SettingsManager settingsManager; private Vibrator vibrator; private ToneGenerator toneGenerator; private boolean isInitialized = false; public NotificationService(Context context) { this.context = context; this.settingsManager = new SettingsManager(context); initializeService(); } /** * Инициализирует сервис уведомлений */ private void initializeService() { try { createAlertChannel(); // Инициализация вибратора if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { VibratorManager vibratorManager = (VibratorManager) context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE); vibrator = vibratorManager.getDefaultVibrator(); } else { vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); } // Инициализация генератора тонов toneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100); isInitialized = true; Log.i(TAG, "Сервис уведомлений инициализирован успешно"); } catch (Exception e) { Log.e(TAG, "Ошибка инициализации сервиса уведомлений: " + e.getMessage(), e); isInitialized = false; } } /** * Создает канал уведомлений для предупреждений (Android O+) */ private void createAlertChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( ALERT_CHANNEL_ID, "AIS Alerts", NotificationManager.IMPORTANCE_HIGH ); channel.setDescription("Сообщения безопасности AIS и предупреждения"); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (nm != null) nm.createNotificationChannel(channel); } } /** * Воспроизводит уведомление о новой AIS цели */ public void notifyNewAISTarget() { if (!isInitialized) { Log.w(TAG, "Сервис уведомлений не инициализирован"); return; } // Проверяем настройки и воспроизводим соответствующие уведомления if (settingsManager.isVibrationEnabled()) { playVibration(); } if (settingsManager.isSoundEnabled()) { playSound(); } Log.i(TAG, "Уведомление о новой AIS цели воспроизведено"); } /** * Воспроизводит вибрацию */ private void playVibration() { try { if (vibrator != null && vibrator.hasVibrator()) { // Паттерн вибрации: короткая пауза, длинная вибрация, короткая пауза, короткая вибрация long[] pattern = {0, 200, 100, 100}; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1); vibrator.vibrate(effect); } else { vibrator.vibrate(pattern, -1); } Log.d(TAG, "Вибрация воспроизведена"); } else { Log.w(TAG, "Вибратор недоступен"); } } catch (Exception e) { Log.e(TAG, "Ошибка воспроизведения вибрации: " + e.getMessage(), e); } } /** * Воспроизводит звуковое уведомление */ private void playSound() { try { if (toneGenerator != null) { // Воспроизводим тон уведомления (TONE_CDMA_ALERT_CALL_GUARD) toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 500); Log.d(TAG, "Звуковое уведомление воспроизведено"); } else { Log.w(TAG, "Генератор тонов недоступен"); } } catch (Exception e) { Log.e(TAG, "Ошибка воспроизведения звука: " + e.getMessage(), e); } } /** * Проверяет, включены ли уведомления */ public boolean areNotificationsEnabled() { return settingsManager.isVibrationEnabled() || settingsManager.isSoundEnabled(); } /** * Проверяет, включена ли вибрация */ public boolean isVibrationEnabled() { return settingsManager.isVibrationEnabled(); } /** * Проверяет, включен ли звук */ public boolean isSoundEnabled() { return settingsManager.isSoundEnabled(); } /** * Уведомление о сообщении безопасности (AIS 14) */ public void notifySafetyMessage(String mmsi, String text) { if (!isInitialized) { Log.w(TAG, "Сервис уведомлений не инициализирован"); return; } // Подаем сигнал по настройкам (вибро/звук) if (settingsManager.isVibrationEnabled()) { playVibration(); } if (settingsManager.isSoundEnabled()) { playSound(); } // Показ системного уведомления в шторке try { createAlertChannel(); Intent intent = new Intent(context, MainActivity.class); int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT : 0; PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, flags); String title = "AIS Safety message"; String content = (text != null && !text.isEmpty()) ? text : ("Сообщение от " + mmsi); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, ALERT_CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(title) .setContentText(content) .setStyle(new NotificationCompat.BigTextStyle().bigText(content)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setContentIntent(pendingIntent) .setAutoCancel(true); int notificationId = SAFETY_NOTIFICATION_ID_BASE + (mmsi != null ? (mmsi.hashCode() & 0x0FFF) : 0); NotificationManagerCompat.from(context).notify(notificationId, builder.build()); Log.i(TAG, "Показано системное уведомление о safety-сообщении: MMSI=" + mmsi); } catch (Exception e) { Log.e(TAG, "Ошибка показа системного уведомления: " + e.getMessage(), e); } } /** * Освобождает ресурсы сервиса */ public void cleanup() { try { if (toneGenerator != null) { toneGenerator.release(); toneGenerator = null; } if (vibrator != null) { vibrator.cancel(); } isInitialized = false; Log.i(TAG, "Ресурсы сервиса уведомлений освобождены"); } catch (Exception e) { Log.e(TAG, "Ошибка при освобождении ресурсов сервиса уведомлений: " + e.getMessage(), e); } } }