2

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:

  • the fired notification doesn't have any sound when the phone is muted or on vibrate so it's not acting like an alarm

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:

  • notification sound works when the phone is muted but no vibration
  • notification sound AND vibration works when the phone is on vibration or with sound enabled

Any ideas how to solve this inconsistency?

adriennoir
  • 1,329
  • 1
  • 15
  • 29

1 Answers1

0

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.

adriennoir
  • 1,329
  • 1
  • 15
  • 29
  • May I know, in term of Notification context, when do you initiate `RingtoneAndVibrationPlayer` creation, and how do you store the reference to your `RingtoneAndVibrationPlayer`? Because, some where at the point, we need a reference to `RingtoneAndVibrationPlayer`, so that we can call `stop()`? Thank you. – Cheok Yan Cheng Oct 06 '18 at 12:40
  • In my use case, I have a RingtoneAndVibrationPlayer member in my Service, initialized in onCreate and then used. – adriennoir Oct 07 '18 at 12:49