'VIBRATOR_SERVICE: String' is deprecated for API 31
Asked Answered
N

9

34

As the title says, i upgraded to API 31. I had a function to perform a vibration, but in the line

val vib = this.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator

the VIBRATOR_SERVICE is now shown as deprecated. How can i replace it? Or at least, what's the modern solution for API 31 and above?

EDIT: as Joachim Sauer wrote, the alternative is VibrationManager. What i need now is the equivalent line of code using VibrationManager.

Newport answered 21/7, 2021 at 8:11 Comment(0)
P
29

The docs for this field say this:

This constant was deprecated in API level 31. Use VibratorManager to retrieve the default system vibrator.

The most direct translation of code needing a Vibrator instance would be this:

val vibratorManager = this.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
val vibrator = vibratorManager.getDefaultVibrator();

Generally speaking whenever a class/method/field is deprecated like this then you should first check the documentation. Almost every single time it will tell you what to use instead (or in some cases that it has no replacement).

Paragraph answered 21/7, 2021 at 8:16 Comment(2)
Thanks, i indeed checked the docs, but it was not clear how to use the VibratorManager, so i got confused and decided to ask it here, since there was no similar question. Basically, excuse my dumbness, i need an example :)Newport
@Joachim Sauer I was just curious to know that how did you figure out the code has to be written this way just by reading docs. As mentioned it can't be directly figured out from the docs sometimes about how to write or implement a particular thing. So how do you do itDehorn
P
68
val vib = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    val vibratorManager =
        getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
    vibratorManager.defaultVibrator
} else {
    @Suppress("DEPRECATION")
    getSystemService(VIBRATOR_SERVICE) as Vibrator
}
Perceptual answered 29/9, 2021 at 9:12 Comment(2)
it's should be marked as the answerInsomnolence
Thanks, your answer is the correct way for offer retrocompatibilityCollation
P
29

The docs for this field say this:

This constant was deprecated in API level 31. Use VibratorManager to retrieve the default system vibrator.

The most direct translation of code needing a Vibrator instance would be this:

val vibratorManager = this.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
val vibrator = vibratorManager.getDefaultVibrator();

Generally speaking whenever a class/method/field is deprecated like this then you should first check the documentation. Almost every single time it will tell you what to use instead (or in some cases that it has no replacement).

Paragraph answered 21/7, 2021 at 8:16 Comment(2)
Thanks, i indeed checked the docs, but it was not clear how to use the VibratorManager, so i got confused and decided to ask it here, since there was no similar question. Basically, excuse my dumbness, i need an example :)Newport
@Joachim Sauer I was just curious to know that how did you figure out the code has to be written this way just by reading docs. As mentioned it can't be directly figured out from the docs sometimes about how to write or implement a particular thing. So how do you do itDehorn
L
4

This code works for both old and new android devices. Reference to the docs Vibrate constantly for the specified period of time.. You should use a VibrationEffect instead to create the vibration pattern.

In Java:

Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

final int DELAY = 0, VIBRATE = 1000, SLEEP = 1000, START = 0;
long[] vibratePattern = {DELAY, VIBRATE, SLEEP};
    
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

   vibrator.vibrate(VibrationEffect.createWaveform(vibratePattern, START));

   } else {
        // backward compatibility for Android API < 26
        // noinspection deprecation
        vibrator.vibrate(vibratePattern, START);
   }

In Kotlin:

val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator

val DELAY = 0
val VIBRATE = 1000
val SLEEP = 1000
val START = 0
val vibratePattern = longArrayOf(DELAY.toLong(), VIBRATE.toLong(), SLEEP.toLong())

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    vibrator.vibrate(VibrationEffect.createWaveform(vibratePattern, START))
} else {
    // backward compatibility for Android API < 26
    // noinspection deprecation
    vibrator.vibrate(vibratePattern, START)
}

Edit

This method works for API level 30 below properly, so to completely use this on API level 31 above you need to use VIBRATOR_MANAGER_SERVICE instead of VIBRATOR_SERVICE, to retrieve the default vibrator service.

The correct code is below (in Java) :

Vibrator vibrator;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {

   VibratorManager vibratorManager = (VibratorManager) getSystemService(Context.VIBRATOR_MANAGER_SERVICE);

   vibrator = vibratorManager.getDefaultVibrator();

  } else {
        // backward compatibility for Android API < 31,
        // VibratorManager was only added on API level 31 release.
        // noinspection deprecation
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

  }

  final int DELAY = 0, VIBRATE = 1000, SLEEP = 1000, START = 0;
  long[] vibratePattern = {DELAY, VIBRATE, SLEEP};
    
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

     vibrator.vibrate(VibrationEffect.createWaveform(vibratePattern, START));

     } else {
          // backward compatibility for Android API < 26
          // noinspection deprecation
          vibrator.vibrate(vibratePattern, START);
     }

The correct code is below (in Kotlin) :

val vibrator: Vibrator

vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    val vibratorManager: VibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
    vibratorManager.getDefaultVibrator()

} else {
    // backward compatibility for Android API < 31,
    // VibratorManager was only added on API level 31 release.
    // noinspection deprecation
    getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}
val DELAY = 0
val VIBRATE = 1000
val SLEEP = 1000
val START = 0
val vibratePattern = longArrayOf(DELAY.toLong(), VIBRATE.toLong(), SLEEP.toLong())

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    vibrator.vibrate(VibrationEffect.createWaveform(vibratePattern, START))

} else {
    // backward compatibility for Android API < 26
    // noinspection deprecation
    vibrator.vibrate(vibratePattern, START)
}
Lavinialavinie answered 29/9, 2021 at 9:27 Comment(2)
VIBRATOR_SERVICE is deprecated.Cheerless
oh, yes, I just read the title again just now. I didn't know that Android 12 made VIBRATOR_SERVICE deprecated. I guess I'll just update my own code to use VIBRATOR_MANAGER_SERVICE instead.Lavinialavinie
O
2

I created a wrapper class to handle the compatibility issue:

class VibratorHelper private constructor(private val context: Context) {

    @Suppress("DEPRECATION")
    fun vibrate(duration: Long) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
            vibratorManager.defaultVibrator.run {
                cancel()
                vibrate(VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE))
            }
        } else {
            val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
            vibrator.cancel()
            if (Build.VERSION.SDK_INT >= 26) {
                vibrator.vibrate(VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE))
            } else {
                vibrator.vibrate(duration)
            }
        }
    }

    companion object {
        @JvmStatic
        fun from(context: Context): VibratorHelper? {
            val hasVibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
                vibratorManager.defaultVibrator.hasVibrator()
            } else {
                @Suppress("DEPRECATION")
                val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
                vibrator.hasVibrator()
            }
            return if (hasVibrator) VibratorHelper(context.applicationContext) else null
        }
    }
}

Here's how to use it:

val vibrator = VibratorHelper.from(context)
vibrator?.vibrate(500)
Outfox answered 8/12, 2022 at 9:20 Comment(0)
P
1

Pulled together the various answers and cleaned them up to take into account changes in SDK 31 and 26, while providing backward compatibility.

@SuppressWarnings("deprecation")
private void vibrate() {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
        VibratorManager vibratorManager = (VibratorManager) getContext().getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
        Vibrator vibrator = vibratorManager.getDefaultVibrator();
        vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
    }
    else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
    } else {
        // API < 26
        Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(500);
    }
}
Peroxide answered 9/11, 2022 at 14:4 Comment(0)
I
1

This is what I use in my app (Kotlin). It handles all the old versions and hides the deprecated warnings. It does one short vibrate.

fun AppCompatActivity.vibrate() {
    val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        getSystemService(AppCompatActivity.VIBRATOR_SERVICE) as Vibrator
    }
    val duration = 200L
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        vibrator.vibrate(VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE))
    } else {
        @Suppress("DEPRECATION")
        vibrator.vibrate(duration)
    }
}
Institutionalize answered 2/2, 2023 at 0:4 Comment(0)
L
0

this is simple answer for both old and new api

Give permission for vibration

<uses-permission android:name="android.permission.VIBRATE" />

After that use this code for kotlin

@Suppress("DEPRECATION")
private fun vibrate(){

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = getSystemService(VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        val vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator
        vibrator.vibrate(10)
    }
}

after that just call the method

Ledge answered 3/3, 2022 at 18:59 Comment(0)
V
0

Handle SDK < 26, 26..32 and >= 33

  private val vibrator: Vibrator by lazy {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
      (getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator
    } else {
      @Suppress("DEPRECATION")
      getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }
  }

 @SuppressLint("MissingPermission")
  private fun startVibrator() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
      vibrator.vibrate(
          VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE),
          VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ALARM)
      )
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      @Suppress("DEPRECATION")
      vibrator.vibrate(
        VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE),
        AudioAttributes.Builder()
          .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
          .setUsage(AudioAttributes.USAGE_ALARM)
          .build()
      )
    } else {
      @Suppress("DEPRECATION")
      vibrator.vibrate(1000)
    }
  }

Volitant answered 14/11, 2022 at 15:40 Comment(0)
D
0

I've created a Context extension for obtaining the Vibrator service:

@SuppressLint("ServiceCast")
fun Context.getVibratorManagerService() =
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager =
            getSystemService(VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        getSystemService(VIBRATOR_SERVICE) as Vibrator
    }


Danieladaniele answered 14/3 at 14:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.