Androidアプリでバイブレーション(振動)を使いたかったのですが、インターフェイスがわかりにくかったので、調べてみました。
まず、対象にするAndroid OSバージョンによって使い方が異なります。
共通
AndroidManifest.xmlでバイブレーションを許可します。
<uses-permission android:name="android.permission.VIBRATE"/>
どのOS向けでも、まずはVibratorを取得します。
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
API level 26 (Android 8.0 Oreo) 未満の場合
1回だけ振動させる
public void vibrate (long milliseconds)
鳴らす時間をミリ秒でセットします。
vibrator.vibrate(300)
2回以上振動させる
public void vibrate (long[] pattern, int repeat)
まず、第一引数として、オン・オフにする時間をミリ秒の配列にしてセットします。配列の最初は待機時間、2つ目はオンになっている時間、3つ目はオフになっている時間・・・、という風に繰り返してセットします。
ずっと振動させ続ける場合は、第二引数に 繰り返しを開始する配列のインデックス をセットします。繰り返し回数では無いので注意してください。繰り返し回数は設定できず、cancelするまで無限に繰り返されます。繰り返ししない場合は、-1をセットします。
「ツートントン」だったらこんなかんじ。
vibrator.vibrate(longArrayOf(0, 1000, 400, 200, 400, 200), -1)
「ツートントントントン・・・・」だったらこんなかんじ。
vibrator.vibrate(longArrayOf(0, 1000, 400, 200, 400, 200), 2)
このままだとアプリをキルするまで永遠に鳴り続けるので、cancelで止めます。
vibrator.cancel()
配列のなかみを説明します。
インデックス | 値 | 振動 |
---|---|---|
0 | 0 | 待機(ここでは待機なし) |
1 | 1000 | 1000ミリ秒鳴らす |
2 | 400 | 400ミリ秒待つ (★) |
3 | 200 | 200ミリ秒鳴らす |
4 | 400 | 400ミリ秒待つ |
5 | 200 | 200ミリ秒鳴らす |
(★)から配列の最後までをずーっと繰り返す設定です。
API level 26 (Android 8.0 Oreo) 以上の場合
API level 26 以上ではVibrationEffectを使います。
1回だけ振動させる
public static VibrationEffect createOneShot (long milliseconds, int amplitude)
第一引数として、鳴らす時間をミリ秒でセットします。
第二引数は、振動の大きさを1〜255の間でセットします。デフォルト値は、VibrationEffect.DEFAULT_AMPLITUDE
です。
val vibrationEffect = VibrationEffect.createOneShot(300, DEFAULT_AMPLITUDE)
vibrator.vibrate(vibrationEffect)
2回以上振動させる
public static VibrationEffect createWaveform(long[] timings, int[] amplitudes, int repeat)
第一引数は、オン・オフにする時間をミリ秒の配列にしてセットします。最初はオフです。
第二引数は、振動の大きさの配列です。第一引数と第二引数の配列サイズはそろえる必要があります。
第三引数は、繰り返しを開始する配列インデックスです。
vibrationEffect = VibrationEffect.createWaveform(longArrayOf(300, 300), intArrayOf(0, DEFAULT_AMPLITUDE), -1)
こんなかんじだと思うのですが、API level 26 以上については実機が手元にないので試せていません… 実機で挙動がおかしかったら教えてください。
どのOSにも対応する
Android OSに関係なく振動させる場合は次のようになります。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val vibrationEffect = VibrationEffect.createOneShot(300, VDEFAULT_AMPLITUDE)
vibrator.vibrate(vibrationEffect)
} else {
vibrator.vibrate(300)
}