androidnotificationsandroid-notificationsandroid-alarmsnotification-channel

NotificationChannel notification as alarm when phone is muted (Oreo)


I'm setting the NotificationCompat.Builder with:

.setSound(getNotificationSound(), AudioManager.STREAM_ALARM)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setPriority(NotificationCompat.PRIORITY_MAX)

among the other mandatory properties.

For the NotificationChannel that I'm using, I added:

.setBypassDnd(true)

For Oreo, the problem is that:

What's the point of Do not disturb custom exception toggle button from a notification category/channel? Can it help to achieve my goal because I didn't see any differences?

For versions older than Oreo, where I'm not using the NotificationChannel I have a behavior which I prefer:

Any ideas how to solve this inconsistency?


Solution

  • In the end I gave up using the notification channels for sound and vibration to get consistent results across Android versions.

    channel.setSound(null, null);
    

    and used the MediaPlayer and Vibrator instead with a helper class like this:

    public class RingtoneAndVibrationPlayer extends ContextWrapper{
    
    private MediaPlayer mMediaPlayer;
    private Vibrator mVibrator;
    
    public RingtoneAndVibrationPlayer(Context context) {
        super(context);
    }
    
    public void play() {
        try {
            mMediaPlayer = new MediaPlayer();
            mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
    
            final Uri uri = Uri.parse(PreferenceHelper.getNotificationSound();
    
            mMediaPlayer.setDataSource(this, uri);
            if (PreferenceHelper.isRingtoneEnabled()) {
                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
                mMediaPlayer.setLooping(PreferenceHelper.isRingtoneInsistent());
                mMediaPlayer.prepareAsync();
            }
    
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mMediaPlayer.start();
                }
            });
    
            if (PreferenceHelper.isVibrationEnabled()) {
                mVibrator.vibrate(new long[] {0, 500, 500, 500},
                        PreferenceHelper.isRingtoneInsistent() ? 2 : -1);
            }
        } catch (SecurityException | IOException e) {
            stop();
        }
    }
    
    public void stop() {
        if (mMediaPlayer != null && mVibrator != null) {
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        if (mVibrator != null) {
            mVibrator.cancel();
        }
    }
    }
    

    The only dissadvantage that I see is that a user could manually change the sound and vibration settings of a notification channel which will play along with the ones above. In my case, this is discouraged by having explicit preferences for sound and vibration in the app's settings.