"VIBRATOR_SERVICE: String" 在 API 31 中已被弃用。

31

正如标题所述,我已经升级到API 31。我有一个执行振动的函数,但在这一行中:

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

VIBRATOR_SERVICE现在已被标记为过时。我该如何替换它?或者至少,在API 31及以上版本中有什么现代解决方案?

编辑:正如Joachim Sauer所写,替代方案是VibrationManager。现在我需要使用VibrationManager的等效代码行。

8个回答

61
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
}

3
答案 - neo
谢谢,你的答案是提供向后兼容性的正确方式。 - Codelaby

28

此字段的文档显示:

此常量已在API级别31中弃用。 请使用 VibratorManager 获取默认的系统振动器。

需要获取 Vibrator 实例的代码最直接的翻译是:

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

一般情况下,当一个类/方法/字段像这样被弃用时,您应该首先查阅文档。几乎每一次,文档都会告诉您要使用什么替代方案(或在某些情况下说明它没有替代方案)。


4
谢谢,我确实查看了文档,但不清楚如何使用VibratorManager,所以感到困惑并决定在这里问一下,因为没有类似的问题。基本上,对我的无知表示抱歉,我需要一个例子 :) - m.i.n.a.r.
@Joachim Sauer,我只是好奇想知道您是如何通过阅读文档就能确定代码必须以这种方式编写的。正如所提到的,有时无法直接从文档中了解如何编写或实现特定的内容。那么您是如何做到的呢? - oyeraghib

4
这段代码适用于新旧版本的安卓设备。 参考文档:持续震动指定时间。你应该使用VibrationEffect来创建震动模式。 在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);
   }

在 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)
}

编辑

此方法适用于API级别30及以下,因此要完全在API级别31以上使用此方法,您需要使用VIBRATOR_MANAGER_SERVICE而不是VIBRATOR_SERVICE来检索默认的振动器服务。

以下是正确的代码(使用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);
     }

正确的代码如下(使用 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)
}

VIBRATOR_SERVICE已被弃用。 - Ramakrishna Joshi
哦,是的,我刚刚重新读了一遍标题。我不知道Android 12会将VIBRATOR_SERVICE弃用。我想我只能更新自己的代码,使用VIBRATOR_MANAGER_SERVICE代替它。 - Noah

1

这是我在我的应用程序(Kotlin)中使用的。它处理所有旧版本并隐藏已弃用的警告。它只会进行一次短震动。

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)
    }
}

1

整理了各种答案并进行了清理,考虑到SDK 31和26的更改,同时提供向后兼容性。

@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);
    }
}

1
我创建了一个包装类来处理兼容性问题:
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
        }
    }
}

以下是使用它的方法:

val vibrator = VibratorHelper.from(context)
vibrator?.vibrate(500)

0

这是旧版和新版 API 的简单答案

允许振动权限

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

然后在 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)
    }
}

之后只需调用该方法即可


0

处理 SDK < 26、26..32 和 >= 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)
    }
  }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接