diff --git a/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt b/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt index 801b275..0eb119a 100644 --- a/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt +++ b/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt @@ -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) + } } }