androidkotlinvibration

How to prevent Android from automatically vibrating on MediaPlayer playback


I have an alarm clock app and some users complain phone vibrates during alarm, while vibrations should be disabled.

After some digging I have found out, that on some devices there's a system option for device to vibrate along alarm music. For example in my test Pixel 4 it is located at Settings->Sound&Vibration->Vibration&Heptics->Alarm vibration.

What this setting, enabled by default, causes, is that vibrations try to "emulate" the music played through MediaPlayer and I cannot find a way to prevent that from happening from within the app or even detect if such setting is present/enabled.

Anyone knows how to get rid of that? Here's a sample method I used for testing:

private fun startThePlayer(context: Context, playInLoop: Boolean = true) {
    try {
        mediaPlayer.reset()
        mediaPlayer.isLooping = playInLoop
        val uri = Settings.System.DEFAULT_RINGTONE_URI
        mediaPlayer.setDataSource(context, uri)
        mediaPlayer.setOnPreparedListener {
            mediaPlayer.start()
        }
        mediaPlayer.prepareAsync()
    } catch (e: Exception) {
        log(e.toString())
    }
}

VIBRATE permission is necessary for this to work.

Effect on Pixel 4 with Android 13: Device is vibrating, as if trying to "emulate" the music played. Vibrations strength depends on value set in device's settings, completely ignoring volume set for alarm's music, and also messing up any vibrations set directly in my app.

What's interesting, is that for some reason Android's default clock app ignores this settings and device doesn't vibrate during it's alarms.


Solution

  • First, I suggest that you use android's VibratorManager to control your app vibrations settings (this is how the android development team called this service.. how bizarre). Use the getDefaultVibrator and cancel methods to stop any vibrations produced by your app (official docs to the rescue)

    Second, because your app is an alarm clock please consider using the setWakeMode which will allow you to keep your app running in the background regardless to the display (in order to prevent the alarm from stopping if the screen is off). Here's the method documentation and also the PowerManager flags documentation

    Hope you will find the right combination to satisfy your needs