type_mate
A Flutter plugin for system-wide writing assistance with overlay bubbles that provide spell checking, grammar fixing, and other writing tools.
“Overlay tools that follow your text fields.”
{"sdk":"flutter"}^2.1.7{"sdk":"flutter"}^5.0.0{"sdk":"flutter"}English project snapshot. Visit GitHub for the latest content.
A Flutter plugin for system-wide writing assistance with overlay bubbles that appear when typing in text fields across all applications.
TypeMate Banner
🔵 System-wide overlay - Works across all Android apps
📱 Text field detection - Automatically detects when you focus on text fields
✍️ Writing assistance - Provides spell check and grammar fix options
🔐 Permission management - Handles overlay and accessibility permissions
⚡ Foreground service - Runs reliably in the background
🎨 Customizable - Configure bubble appearance and behavior
| Platform | Support |
|---|---|
| Android | ✅ Full support |
| iOS | ❌ Not supported (iOS limitations) |
| Web | ❌ Not applicable |
| Desktop | ❌ Not supported |
Add this to your package's pubspec.yaml file:
dependencies:
type_mate: ^1.0.0
android/app/src/main/AndroidManifest.xml:<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
AndroidManifest.xml inside the <application> tag:<!-- Overlay Service -->
<service
android:name="com.ratulhasanruhan.type_mate.OverlayService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="mediaProjection" />
<!-- Accessibility Service -->
<service
android:name="com.ratulhasanruhan.type_mate.TextAccessibilityService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
import 'package:type_mate/type_mate.dart';
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
_setupTypeMate();
}
Future<void> _setupTypeMate() async {
// Initialize the plugin
await TypeMate.instance.initialize();
// Listen to text field focus events
TypeMate.instance.textFieldFocusedStream.listen((_) {
print('Text field focused in external app');
});
// Quick setup with all necessary steps
final result = await TypeMate.instance.quickSetup();
if (result['serviceStarted'] == true) {
print('TypeMate is ready!');
}
}
}
// Check permissions
bool hasOverlayPermission = await TypeMate.instance.checkOverlayPermission();
bool hasAccessibilityService = await TypeMate.instance.checkAccessibilityService();
// Request permissions
if (!hasOverlayPermission) {
await TypeMate.instance.requestOverlayPermission();
}
if (!hasAccessibilityService) {
await TypeMate.instance.openAccessibilitySettings();
}
// Start/Stop overlay service
await TypeMate.instance.startOverlayService();
await TypeMate.instance.stopOverlayService();
// Test the overlay
await TypeMate.instance.testOverlay();
// Get comprehensive status
Map<String, dynamic> status = await TypeMate.instance.getStatus();
print('Status: $status');
You can customize the overlay behavior using OverlayConfig:
final config = OverlayConfig(
autoShow: true,
autoHideDuration: 3000, // milliseconds
enableVibration: false,
bubbleSize: 56.0,
bubbleOpacity: 0.9,
enableSpellCheck: true,
enableGrammarCheck: true,
initialX: 100,
initialY: 200,
);
// Use config when starting the service (planned for future versions)
TypeMate consists of three main components:
User types in any app
↓
Accessibility Service detects text input
↓
Triggers Overlay Service
↓
Bubble appears with writing assistance options
↓
User can check spelling/grammar or close bubble
The plugin comes with a complete example app that demonstrates all features:
cd example
flutter run
The example app includes:
Main plugin class providing all functionality.
| Method | Return Type | Description |
|---|---|---|
initialize() |
Future<bool> |
Initialize the plugin |
checkOverlayPermission() |
Future<bool> |
Check if overlay permission is granted |
requestOverlayPermission() |
Future<void> |
Request overlay permission |
checkAccessibilityService() |
Future<bool> |
Check if accessibility service is enabled |
openAccessibilitySettings() |
Future<void> |
Open accessibility settings |
startOverlayService() |
Future<void> |
Start the overlay service |
stopOverlayService() |
Future<void> |
Stop the overlay service |
testOverlay() |
Future<void> |
Show test bubble for 3 seconds |
quickSetup() |
Future<Map<String, bool>> |
Perform complete setup |
getStatus() |
Future<Map<String, dynamic>> |
Get comprehensive status |
| Stream | Type | Description |
|---|---|---|
textFieldFocusedStream |
Stream<void> |
Notifies when text fields are focused |
textFieldUnfocusedStream |
Stream<void> |
Notifies when text fields lose focus |
Bubble not appearing:
Accessibility service not working:
Permission requests failing:
Enable verbose logging to see what's happening:
// Check status regularly
Timer.periodic(Duration(seconds: 5), (timer) async {
final status = await TypeMate.instance.getStatus();
print('TypeMate Status: $status');
});
Contributions are welcome! Please read our contributing guidelines and submit pull requests to help improve TypeMate.
This project is licensed under the MIT License - see the LICENSE file for details.
Based on the focus_bubble project architecture and inspired by system-wide writing assistance tools.
If you find this plugin useful, please consider giving it a star ⭐ on GitHub and sharing it with the Flutter community!