Skip to main content

sms_sender_plus 0.1.0 copy "sms_sender_plus: ^0.1.0" to clipboard
sms_sender_plus: ^0.1.0 copied to clipboard

Send SMS from Flutter with Android SIM selection, delivery status, batch recipients, and iOS composer support.

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sms_sender_plus/sms_sender_plus.dart';

void main() {
  runApp(const SmsSenderPlusExampleApp());
}

class SmsSenderPlusExampleApp extends StatelessWidget {
  const SmsSenderPlusExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'sms_sender_plus example',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.teal),
      home: const SmsExampleScreen(),
    );
  }
}

class SmsExampleScreen extends StatefulWidget {
  const SmsExampleScreen({super.key});

  @override
  State<SmsExampleScreen> createState() => _SmsExampleScreenState();
}

class _SmsExampleScreenState extends State<SmsExampleScreen> {
  final _recipientController = TextEditingController();
  final _batchController = TextEditingController();
  final _messageController = TextEditingController(
    text: 'Hello from sms_sender_plus',
  );
  final _events = <String>[];

  List<SimCard> _simCards = const [];
  int? _selectedSlot;
  bool _deliveryReport = true;
  bool _busy = false;
  StreamSubscription<SmsStatusEvent>? _statusSubscription;

  @override
  void initState() {
    super.initState();
    _statusSubscription = SmsSenderPlus.instance.statusEvents.listen((event) {
      _addEvent(
        '${event.messageId}: ${event.status.name} ${event.recipient ?? ''}',
      );
    });
    _loadSimCards();
  }

  @override
  void dispose() {
    _statusSubscription?.cancel();
    _recipientController.dispose();
    _batchController.dispose();
    _messageController.dispose();
    super.dispose();
  }

  Future<void> _loadSimCards() async {
    await _requestAndroidPermissions();
    await _run(() async {
      final simCards = await SmsSenderPlus.instance.getSimCards();
      setState(() => _simCards = simCards);
    });
  }

  Future<void> _requestAndroidPermissions() async {
    await [Permission.sms, Permission.phone].request();
  }

  Future<void> _sendSingle() async {
    await _run(() async {
      final result = await SmsSenderPlus.instance.sendTextMessage(
        recipient: _recipientController.text,
        message: _messageController.text,
        simSlot: _selectedSlot,
        deliveryReport: _deliveryReport,
      );
      _addEvent('single result: ${result.state.name} ${result.messageId}');
    });
  }

  Future<void> _sendBatch() async {
    await _run(() async {
      final result = await SmsSenderPlus.instance.sendTextMessages(
        recipients: _batchController.text.split(','),
        message: _messageController.text,
        simSlot: _selectedSlot,
      );
      _addEvent('batch result: ${result.state.name} ${result.messageId}');
    });
  }

  Future<void> _run(Future<void> Function() action) async {
    setState(() => _busy = true);
    try {
      await action();
    } on SmsSenderPlusException catch (error) {
      _addEvent('${error.code}: ${error.message}');
    } finally {
      if (mounted) {
        setState(() => _busy = false);
      }
    }
  }

  void _addEvent(String message) {
    if (!mounted) {
      return;
    }
    setState(() => _events.insert(0, message));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('sms_sender_plus')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          TextField(
            controller: _recipientController,
            keyboardType: TextInputType.phone,
            decoration: const InputDecoration(labelText: 'Single recipient'),
          ),
          const SizedBox(height: 12),
          TextField(
            controller: _batchController,
            keyboardType: TextInputType.phone,
            decoration: const InputDecoration(
              labelText: 'Batch recipients, comma separated',
            ),
          ),
          const SizedBox(height: 12),
          TextField(
            controller: _messageController,
            minLines: 3,
            maxLines: 5,
            decoration: const InputDecoration(labelText: 'Message'),
          ),
          const SizedBox(height: 12),
          DropdownButtonFormField<int?>(
            initialValue: _selectedSlot,
            decoration: const InputDecoration(labelText: 'SIM slot'),
            items: [
              const DropdownMenuItem<int?>(
                value: null,
                child: Text('Device default'),
              ),
              ..._simCards.map(
                (sim) => DropdownMenuItem<int?>(
                  value: sim.simSlotIndex,
                  child: Text(
                    'Slot ${sim.simSlotIndex}: '
                    '${sim.carrierName ?? sim.displayName ?? sim.subscriptionId}',
                  ),
                ),
              ),
            ],
            onChanged: (value) => setState(() => _selectedSlot = value),
          ),
          SwitchListTile(
            value: _deliveryReport,
            title: const Text('Delivery report for single SMS'),
            onChanged: (value) => setState(() => _deliveryReport = value),
          ),
          const SizedBox(height: 12),
          FilledButton(
            onPressed: _busy ? null : _sendSingle,
            child: const Text('Send single'),
          ),
          OutlinedButton(
            onPressed: _busy ? null : _sendBatch,
            child: const Text('Send batch'),
          ),
          const SizedBox(height: 24),
          Text('Events', style: Theme.of(context).textTheme.titleMedium),
          const SizedBox(height: 8),
          for (final event in _events) Text(event),
        ],
      ),
    );
  }
}
2
likes
140
points
78
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Send SMS from Flutter with Android SIM selection, delivery status, batch recipients, and iOS composer support.

Repository (GitHub)
View/report issues

Topics

#sms #telephony #android #ios #dual-sim

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on sms_sender_plus

Packages that implement sms_sender_plus