diff --git a/lib/bridge/handlers/device_bridge_handler.dart b/lib/bridge/handlers/device_bridge_handler.dart index 750a1c5..9e54428 100644 --- a/lib/bridge/handlers/device_bridge_handler.dart +++ b/lib/bridge/handlers/device_bridge_handler.dart @@ -5,6 +5,7 @@ import 'package:app/permissions/FirebaseConfig.dart'; import 'package:app/utils/env/env.dart'; import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:vibration/vibration.dart'; /// 디바이스 토큰, 햅틱, 환경 전환 관련 브릿지 핸들러 mixin DeviceBridgeHandler on BridgeHandlerBase { @@ -43,24 +44,51 @@ mixin DeviceBridgeHandler on BridgeHandlerBase { return; } - switch (hapticType) { - case 'light': - await HapticFeedback.lightImpact(); - break; - case 'medium': - await HapticFeedback.mediumImpact(); - break; - case 'heavy': - await HapticFeedback.heavyImpact(); - break; - case 'selection': - await HapticFeedback.selectionClick(); - break; - case 'vibrate': - await HapticFeedback.vibrate(); - break; - default: - logger.w('Unknown haptic feedback type: $hapticType'); + if (Platform.isAndroid && + await Vibration.hasAmplitudeControl() == true) { + // Android: Vibration API로 amplitude 직접 제어 + // amplitude 기준: expo-haptics 프로덕션 값 + Android 공식 디자인 가이드 + // 레벨 간 최소 1.4배 차이 유지 (Android Haptics Design Principles) + switch (hapticType) { + case 'light': + await Vibration.vibrate(duration: 50, amplitude: 30); + break; + case 'medium': + await Vibration.vibrate(duration: 43, amplitude: 50); + break; + case 'heavy': + await Vibration.vibrate(duration: 60, amplitude: 70); + break; + case 'selection': + await Vibration.vibrate(duration: 20, amplitude: 20); + break; + case 'vibrate': + await Vibration.vibrate(duration: 500, amplitude: 128); + break; + default: + logger.w('Unknown haptic feedback type: $hapticType'); + } + } else { + // iOS 또는 amplitude 미지원 Android: Flutter 기본 API 사용 + switch (hapticType) { + case 'light': + await HapticFeedback.lightImpact(); + break; + case 'medium': + await HapticFeedback.mediumImpact(); + break; + case 'heavy': + await HapticFeedback.heavyImpact(); + break; + case 'selection': + await HapticFeedback.selectionClick(); + break; + case 'vibrate': + await HapticFeedback.vibrate(); + break; + default: + logger.w('Unknown haptic feedback type: $hapticType'); + } } } else { logger.w( diff --git a/pubspec.lock b/pubspec.lock index 1b4b555..5b951e8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -257,6 +257,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.10" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da" + url: "https://pub.dev" + source: hosted + version: "11.3.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" dio: dependency: transitive description: @@ -1389,6 +1405,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vibration: + dependency: "direct main" + description: + name: vibration + sha256: "3b08a0579c2f9c18d5d78cb5c74f1005f731e02eeca6d72561a2e8059bf98ec3" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + vibration_platform_interface: + dependency: transitive + description: + name: vibration_platform_interface + sha256: "6ffeee63547562a6fef53c05a41d4fdcae2c0595b83ef59a4813b0612cd2bc36" + url: "https://pub.dev" + source: hosted + version: "0.0.3" vm_service: dependency: transitive description: @@ -1469,6 +1501,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.13.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" + url: "https://pub.dev" + source: hosted + version: "1.1.5" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index eda00c8..2e16be3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,6 +28,7 @@ dependencies: flutter_native_splash: ^2.4.6 shared_preferences: ^2.5.2 share_plus: ^10.1.4 + vibration: ^2.0.0 dev_dependencies: flutter_test: