quipuscore_sms_plugin 0.0.1
quipuscore_sms_plugin: ^0.0.1 copied to clipboard
A Flutter plugin for reading SMS messages from Android devices and syncing them to a backend server. Integrates with SMS SDK Android library via Maven.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:quipuscore_sms_plugin/quipuscore_sms_plugin.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SMS Plugin Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const MyHomePage(title: 'SMS Plugin Flutter Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _smsPlugin = SmsPluginFlutter();
final _clientIdController = TextEditingController(text: 'my-flutter-app');
final _tokenController = TextEditingController();
final _deviceIdController = TextEditingController(text: 'test-device-123');
final _userIdController = TextEditingController(text: 'test-user-456');
bool _isInitialized = false;
String _statusMessage = 'Not initialized';
bool _isLoading = false;
@override
void dispose() {
_clientIdController.dispose();
_tokenController.dispose();
_deviceIdController.dispose();
_userIdController.dispose();
super.dispose();
}
Future<void> _initialize() async {
if (_tokenController.text.isEmpty) {
_showMessage('Please enter a token', isError: true);
return;
}
setState(() {
_isLoading = true;
_statusMessage = 'Initializing...';
});
try {
final result = await _smsPlugin.initialize(
InitializeOptions(
clientId: _clientIdController.text,
token: _tokenController.text,
),
);
setState(() {
_isInitialized = result.success;
_statusMessage = result.message;
_isLoading = false;
});
_showMessage(result.message, isError: !result.success);
} on PlatformException catch (e) {
setState(() {
_isInitialized = false;
_statusMessage = 'Error: ${e.message}';
_isLoading = false;
});
_showMessage('Initialization failed: ${e.message}', isError: true);
}
}
Future<void> _collectAndSync() async {
if (!_isInitialized) {
_showMessage('Please initialize first', isError: true);
return;
}
if (_deviceIdController.text.isEmpty) {
_showMessage('Please enter a device ID', isError: true);
return;
}
setState(() {
_isLoading = true;
_statusMessage = 'Collecting and syncing SMS...';
});
try {
final result = await _smsPlugin.collectAndSync(
CollectAndSyncOptions(
deviceId: _deviceIdController.text,
userId: _userIdController.text.isNotEmpty
? _userIdController.text
: null,
),
);
setState(() {
_statusMessage = result.message;
_isLoading = false;
});
_showMessage(result.message, isError: !result.success);
} on PlatformException catch (e) {
setState(() {
_statusMessage = 'Error: ${e.message}';
_isLoading = false;
});
_showMessage('Sync failed: ${e.message}', isError: true);
}
}
Future<void> _linkUserDevice() async {
if (!_isInitialized) {
_showMessage('Please initialize first', isError: true);
return;
}
if (_userIdController.text.isEmpty || _deviceIdController.text.isEmpty) {
_showMessage('Please enter both user ID and device ID', isError: true);
return;
}
setState(() {
_isLoading = true;
_statusMessage = 'Linking user with device...';
});
try {
final result = await _smsPlugin.linkUserIdWithDevice(
LinkUserIdWithDeviceOptions(
userId: _userIdController.text,
deviceId: _deviceIdController.text,
),
);
setState(() {
_statusMessage = result.message;
_isLoading = false;
});
_showMessage(result.message, isError: !result.success);
} on PlatformException catch (e) {
setState(() {
_statusMessage = 'Error: ${e.message}';
_isLoading = false;
});
_showMessage('Link failed: ${e.message}', isError: true);
}
}
void _showMessage(String message, {bool isError = false}) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: isError ? Colors.red : Colors.green,
duration: const Duration(seconds: 3),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Status Card
Card(
color: _isInitialized ? Colors.green.shade50 : Colors.grey.shade100,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Icon(
_isInitialized ? Icons.check_circle : Icons.info_outline,
size: 48,
color: _isInitialized ? Colors.green : Colors.grey,
),
const SizedBox(height: 8),
Text(
_statusMessage,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
),
],
),
),
),
const SizedBox(height: 24),
// Initialize Section
Text(
'1. Initialize Plugin',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
TextField(
controller: _clientIdController,
decoration: const InputDecoration(
labelText: 'Client ID',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 8),
TextField(
controller: _tokenController,
decoration: const InputDecoration(
labelText: 'API Token',
border: OutlineInputBorder(),
hintText: 'Enter your API token',
),
obscureText: true,
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: _isLoading ? null : _initialize,
child: const Text('Initialize'),
),
const SizedBox(height: 24),
// Device and User IDs Section
Text(
'2. Enter Device & User IDs',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
TextField(
controller: _deviceIdController,
decoration: const InputDecoration(
labelText: 'Device ID',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 8),
TextField(
controller: _userIdController,
decoration: const InputDecoration(
labelText: 'User ID (Optional)',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 24),
// Actions Section
Text(
'3. Actions',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
ElevatedButton.icon(
onPressed: _isLoading ? null : _collectAndSync,
icon: const Icon(Icons.sync),
label: const Text('Collect & Sync SMS'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(16),
),
),
const SizedBox(height: 8),
ElevatedButton.icon(
onPressed: _isLoading ? null : _linkUserDevice,
icon: const Icon(Icons.link),
label: const Text('Link User with Device'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(16),
),
),
const SizedBox(height: 24),
// Information Card
Card(
color: Colors.blue.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.info, color: Colors.blue.shade700),
const SizedBox(width: 8),
Text(
'How to use',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.blue.shade700,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 8),
const Text(
'1. Initialize the plugin with your API token\n'
'2. Enter device and user IDs\n'
'3. Collect & Sync to read and send SMS to server\n'
'4. Link User to associate user with device\n\n'
'Note: The app will request READ_SMS permission when needed.',
style: TextStyle(fontSize: 14),
),
],
),
),
),
],
),
),
);
}
}