Make HapticFeedback null-safe for devices without vibrator
Use safe cast (as? VibratorManager) and wrap vibrate calls in try-catch to prevent crashes on emulators, custom ROMs, or devices without vibration hardware. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0e9adebe78
commit
4950feb751
1 changed files with 24 additions and 8 deletions
|
|
@ -2,37 +2,45 @@ package no.naiv.tiltshift.util
|
|||
|
||||
import android.content.Context
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.os.VibratorManager
|
||||
import android.util.Log
|
||||
|
||||
/**
|
||||
* Provides haptic feedback for user interactions.
|
||||
* Gracefully degrades on devices without vibration hardware.
|
||||
*/
|
||||
class HapticFeedback(private val context: Context) {
|
||||
|
||||
private val vibrator by lazy {
|
||||
val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
|
||||
vibratorManager.defaultVibrator
|
||||
companion object {
|
||||
private const val TAG = "HapticFeedback"
|
||||
}
|
||||
|
||||
private val vibrator: Vibrator? by lazy {
|
||||
val vibratorManager =
|
||||
context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as? VibratorManager
|
||||
vibratorManager?.defaultVibrator
|
||||
}
|
||||
|
||||
/**
|
||||
* Light tick for UI feedback (button press, slider change).
|
||||
*/
|
||||
fun tick() {
|
||||
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
|
||||
vibrateOrLog(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
|
||||
}
|
||||
|
||||
/**
|
||||
* Click feedback for confirmations.
|
||||
*/
|
||||
fun click() {
|
||||
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
|
||||
vibrateOrLog(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
|
||||
}
|
||||
|
||||
/**
|
||||
* Heavy click for important actions (photo capture).
|
||||
*/
|
||||
fun heavyClick() {
|
||||
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK))
|
||||
vibrateOrLog(VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -41,7 +49,7 @@ class HapticFeedback(private val context: Context) {
|
|||
fun success() {
|
||||
val timings = longArrayOf(0, 30, 50, 30)
|
||||
val amplitudes = intArrayOf(0, 100, 0, 200)
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1))
|
||||
vibrateOrLog(VibrationEffect.createWaveform(timings, amplitudes, -1))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,6 +58,14 @@ class HapticFeedback(private val context: Context) {
|
|||
fun error() {
|
||||
val timings = longArrayOf(0, 50, 30, 50, 30, 50)
|
||||
val amplitudes = intArrayOf(0, 150, 0, 150, 0, 150)
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1))
|
||||
vibrateOrLog(VibrationEffect.createWaveform(timings, amplitudes, -1))
|
||||
}
|
||||
|
||||
private fun vibrateOrLog(effect: VibrationEffect) {
|
||||
try {
|
||||
vibrator?.vibrate(effect)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Haptic feedback failed", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue