flutter_voice_otp 1.0.2
flutter_voice_otp: ^1.0.2 copied to clipboard
A production-ready Flutter widget for entering OTPs via keyboard or voice, with automatic spoken-number-to-digit conversion.
flutter_voice_otp #
A production-ready Flutter widget for entering One-Time Passcodes (OTPs) via
keyboard or voice. Speak a code like "one two three four" or "1 2 3
4" and flutter_voice_otp automatically converts it into the numeric OTP
value β no manual typing required.
Features #
- π’ Supports OTP lengths of 4, 5, 6, or any custom length.
- β¨οΈ Manual keyboard entry with automatic focus traversal between boxes.
- ποΈ Built-in microphone button for voice-driven entry.
- π£οΈ Converts spoken numbers β spelled out (
"one two three"), digit-by-digit ("1 2 3"), or mixed β into a clean numeric string, ignoring filler words. - π A single shared
TextEditingControlleralways holds the complete OTP. - β Built-in and custom validation, with automatic error-border styling.
- π¨ Fully customizable: border color, focused/error border color, fill color, border radius, spacing, box size, text style, cursor color.
- π Light and dark theme support out of the box.
- π§± Clean architecture: widgets, controller, speech service, and utilities are cleanly separated for testability and maintainability.
Getting started #
Add the dependency:
dependencies:
flutter_voice_otp: ^1.0.0
This package uses speech_to_text
for voice recognition, which requires platform permissions.
Android #
Add to android/app/src/main/AndroidManifest.xml (inside <manifest>):
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
</intent>
</queries>
iOS #
Add to ios/Runner/Info.plist (inside the top-level <dict>):
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access so you can enter your OTP by voice.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>This app uses speech recognition to convert your spoken OTP into digits.</string>
See example/android and example/ios in this repository for full manifest
and plist snippets.
Basic usage #
import 'package:flutter_voice_otp/flutter_voice_otp.dart';
VoiceOtpField(
length: 6,
onCompleted: (otp) {
// Called exactly once the OTP reaches 6 digits.
verifyOtp(otp);
},
)
Using a shared controller #
The OTP value is always available through a single
TextEditingController, whether it was typed or spoken:
final otpController = TextEditingController();
VoiceOtpField(
length: 4,
controller: otpController,
)
// Read the value anywhere:
print(otpController.text);
// Or set it programmatically:
otpController.text = '1234';
Voice input behavior #
Tapping the microphone button starts a listening session. As speech is
recognized, flutter_voice_otp extracts digits from the transcript using
WordToDigitConverter, which
understands:
| Spoken phrase | Resulting OTP |
|---|---|
| "One Two Three Four" | 1234 |
| "1 2 3 4" | 1234 |
| "One Two Three Four Five Six" | 123456 |
| "the code is one two three four" | 1234 |
| "double one two" | 112 |
Validation #
VoiceOtpField(
length: 4,
autovalidate: true,
validator: (otp) {
if (otp.length < 4) return null; // wait until fully typed
if (otp != '1234') return 'Incorrect code';
return null;
},
)
When a validator returns a non-null message, every box switches to the
configured errorBorderColor and the message is displayed beneath the
field. OtpValidator.defaultValidator is available as a ready-made numeric
- length check.
Full customization #
VoiceOtpField(
length: 4,
theme: VoiceOtpTheme(
borderColor: Colors.grey.shade300,
focusedBorderColor: Colors.deepPurple,
errorBorderColor: Colors.red,
fillColor: Colors.grey.shade50,
borderRadius: 16,
spacing: 12,
boxWidth: 56,
boxHeight: 60,
textStyle: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
cursorColor: Colors.deepPurple,
),
)
Light / dark themes #
By default VoiceOtpField derives its theme from the ambient
Theme.of(context).brightness. You can also force one explicitly:
VoiceOtpField(
length: 6,
brightness: Brightness.dark, // or Brightness.light
)
// Or supply an already-built theme object directly:
VoiceOtpField(
length: 6,
theme: VoiceOtpTheme.dark(),
)
Callbacks reference #
| Callback | Fired when⦠|
|---|---|
onChanged |
The OTP value changes, from typing or voice. |
onCompleted |
The OTP reaches the configured length. |
onVoiceDetected |
A speech transcript (partial or final) is recognized. |
onListeningStart |
A voice-recognition session begins. |
onListeningStop |
A voice-recognition session ends. |
onVoiceError |
Speech recognition fails (permission denied, unavailable...). |
Example app #
The example/ directory contains a full demo app covering:
- Basic Voice OTP Field
- Custom styling
- Validation
- Voice input
- Manual keyboard input
- Using a single
TextEditingController - Auto-completion callback
Run it with:
cd example
flutter run
Architecture #
lib/
flutter_voice_otp.dart # Public exports
src/
voice_otp_field.dart # Main widget (composition root)
voice_controller.dart # State + callback orchestration
speech_service.dart # Thin wrapper around speech_to_text
voice_button.dart # Microphone button widget
otp_box.dart # Single digit box widget
models/
voice_otp_theme.dart # Styling configuration
voice_status.dart # Voice lifecycle enum
utils/
word_to_digit_converter.dart # Spoken text -> digits
otp_validator.dart # Validation helpers
Contributing #
Issues and pull requests are welcome. Please run flutter analyze and
flutter test before submitting.
License #
MIT β see LICENSE.