NotificationsSettingsFragment.java

  1package eu.siacs.conversations.ui.fragment.settings;
  2
  3import android.app.NotificationChannel;
  4import android.media.RingtoneManager;
  5import android.net.Uri;
  6import android.os.Build;
  7import android.os.Bundle;
  8import android.util.Log;
  9
 10import androidx.activity.result.ActivityResultLauncher;
 11import androidx.annotation.NonNull;
 12import androidx.annotation.Nullable;
 13import androidx.preference.Preference;
 14
 15import com.google.common.base.Optional;
 16
 17import eu.siacs.conversations.AppSettings;
 18import eu.siacs.conversations.Config;
 19import eu.siacs.conversations.R;
 20import eu.siacs.conversations.services.NotificationService;
 21import eu.siacs.conversations.ui.activity.result.PickRingtone;
 22import eu.siacs.conversations.utils.Compatibility;
 23
 24public class NotificationsSettingsFragment extends XmppPreferenceFragment {
 25
 26    private final ActivityResultLauncher<Uri> pickNotificationToneLauncher =
 27            registerForActivityResult(
 28                    new PickRingtone(RingtoneManager.TYPE_NOTIFICATION),
 29                    result -> {
 30                        if (result == null) {
 31                            // do nothing. user aborted
 32                            return;
 33                        }
 34                        final Uri uri = PickRingtone.noneToNull(result);
 35                        appSettings().setNotificationTone(uri);
 36                        Log.i(Config.LOGTAG, "User set notification tone to " + uri);
 37                    });
 38    private final ActivityResultLauncher<Uri> pickRingtoneLauncher =
 39            registerForActivityResult(
 40                    new PickRingtone(RingtoneManager.TYPE_RINGTONE),
 41                    result -> {
 42                        if (result == null) {
 43                            // do nothing. user aborted
 44                            return;
 45                        }
 46                        final Uri uri = PickRingtone.noneToNull(result);
 47                        appSettings().setRingtone(uri);
 48                        Log.i(Config.LOGTAG, "User set ringtone to " + uri);
 49                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 50                            NotificationService.recreateIncomingCallChannel(requireContext(), uri);
 51                        }
 52                    });
 53
 54    @Override
 55    public void onCreatePreferences(
 56            @Nullable final Bundle savedInstanceState, final @Nullable String rootKey) {
 57        setPreferencesFromResource(R.xml.preferences_notifications, rootKey);
 58        final var messageNotificationSettings = findPreference("message_notification_settings");
 59        final var notificationRingtone = findPreference(AppSettings.NOTIFICATION_RINGTONE);
 60        final var notificationHeadsUp = findPreference(AppSettings.NOTIFICATION_HEADS_UP);
 61        final var notificationVibrate = findPreference(AppSettings.NOTIFICATION_VIBRATE);
 62        final var notificationLed = findPreference(AppSettings.NOTIFICATION_LED);
 63        final var foregroundService = findPreference(AppSettings.KEEP_FOREGROUND_SERVICE);
 64        if (messageNotificationSettings == null
 65                || notificationRingtone == null
 66                || notificationHeadsUp == null
 67                || notificationVibrate == null
 68                || notificationLed == null
 69                || foregroundService == null) {
 70            throw new IllegalStateException("The preference resource file is missing preferences");
 71        }
 72        if (Compatibility.runsTwentySix()) {
 73            notificationRingtone.setVisible(false);
 74            notificationHeadsUp.setVisible(false);
 75            notificationVibrate.setVisible(false);
 76            notificationLed.setVisible(false);
 77            foregroundService.setVisible(false);
 78        } else {
 79            messageNotificationSettings.setVisible(false);
 80        }
 81    }
 82
 83    @Override
 84    protected void onSharedPreferenceChanged(@NonNull String key) {
 85        super.onSharedPreferenceChanged(key);
 86        if (key.equals(AppSettings.KEEP_FOREGROUND_SERVICE)) {
 87            requireService().toggleForegroundService();
 88        }
 89    }
 90
 91    @Override
 92    public void onStart() {
 93        super.onStart();
 94        requireActivity().setTitle(R.string.notifications);
 95    }
 96
 97    @Override
 98    public boolean onPreferenceTreeClick(final Preference preference) {
 99        final var key = preference.getKey();
100        if (AppSettings.RINGTONE.equals(key)) {
101            pickRingtone();
102            return true;
103        }
104        if (AppSettings.NOTIFICATION_RINGTONE.equals(key)) {
105            pickNotificationTone();
106            return true;
107        }
108        return super.onPreferenceTreeClick(preference);
109    }
110
111    private void pickNotificationTone() {
112        final Uri uri = appSettings().getNotificationTone();
113        Log.i(Config.LOGTAG, "current notification tone: " + uri);
114        this.pickNotificationToneLauncher.launch(uri);
115    }
116
117    private void pickRingtone() {
118        final Optional<Uri> channelRingtone;
119        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
120            channelRingtone =
121                    NotificationService.getCurrentIncomingCallChannel(requireContext())
122                            .transform(channel -> PickRingtone.nullToNone(channel.getSound()));
123        } else {
124            channelRingtone = Optional.absent();
125        }
126        final Uri uri;
127        if (channelRingtone.isPresent()) {
128            uri = channelRingtone.get();
129            Log.d(Config.LOGTAG, "ringtone came from channel");
130        } else {
131            uri = appSettings().getRingtone();
132        }
133        Log.i(Config.LOGTAG, "current ringtone: " + uri);
134        this.pickRingtoneLauncher.launch(uri);
135    }
136
137    private AppSettings appSettings() {
138        return new AppSettings(requireContext());
139    }
140}