flutter_alarmkit 0.0.2 copy "flutter_alarmkit: ^0.0.2" to clipboard
flutter_alarmkit: ^0.0.2 copied to clipboard

A Flutter plugin for AlarmKit.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_alarmkit/flutter_alarmkit.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  String _authStatus = 'Not requested';
  String _scheduleStatus = 'No alarm scheduled';
  String? _lastAlarmId;
  final _flutterAlarmkitPlugin = FlutterAlarmkit();

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    try {
      platformVersion =
          await _flutterAlarmkitPlugin.getPlatformVersion() ??
          'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  Future<void> _requestAuthorization() async {
    setState(() {
      _authStatus = 'Requesting...';
    });

    try {
      final bool granted = await _flutterAlarmkitPlugin.requestAuthorization();
      if (!mounted) return;

      setState(() {
        _authStatus = granted ? 'Granted' : 'Denied';
      });
    } on PlatformException catch (e) {
      if (e.code == 'UNSUPPORTED_VERSION') {
        _authStatus = 'iOS 26.0+ required';
      }
      if (!mounted) return;

      setState(() {
        _authStatus = 'Error: ${e.message}';
      });
    }
  }

  Future<void> _scheduleTestAlarm() async {
    setState(() {
      _scheduleStatus = 'Scheduling...';
      _lastAlarmId = null;
    });

    try {
      // First ensure we have authorization
      if (_authStatus != 'Granted') {
        final granted = await _flutterAlarmkitPlugin.requestAuthorization();

        if (!mounted) return;

        if (!granted) {
          setState(() {
            _authStatus = 'Denied';
            _scheduleStatus = 'Please grant alarm permission in Settings';
          });
          return;
        }

        setState(() {
          _authStatus = 'Granted';
        });
      }

      // Schedule alarm for 5 seconds from now
      final timestamp =
          DateTime.now()
              .add(const Duration(seconds: 5))
              .millisecondsSinceEpoch
              .toDouble();

      final alarmId = await _flutterAlarmkitPlugin.scheduleOneShotAlarm(
        timestamp: timestamp,
        label: 'Test Alarm',
      );

      if (!mounted) return;

      setState(() {
        _scheduleStatus = 'Alarm scheduled!';
        _lastAlarmId = alarmId;
      });
    } on PlatformException catch (e) {
      if (!mounted) return;

      setState(() {
        switch (e.code) {
          case 'UNSUPPORTED_VERSION':
            _scheduleStatus = 'iOS 26.0+ required';
          case 'NOT_AUTHORIZED':
            _scheduleStatus = 'Authorization failed: ${e.message}';
            // Force a refresh of the authorization state
            _authStatus = 'Unknown';
          case 'AUTH_ERROR':
            _scheduleStatus = 'Authorization error: ${e.message}';
            _authStatus = 'Error';
          default:
            _scheduleStatus = 'Error: ${e.message}';
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('AlarmKit Example 0.0.2')),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Running on: $_platformVersion'),
                const SizedBox(height: 20),
                const Text(
                  'Alarm Permission Status:',
                  style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 8),
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: _getStatusColor(),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Text(
                    _authStatus,
                    style: const TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
                const SizedBox(height: 20),
                ElevatedButton(
                  onPressed: _requestAuthorization,
                  child: const Text('Request Alarm Permission'),
                ),
                const SizedBox(height: 40),
                const Text(
                  'Test Alarm:',
                  style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 8),
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: _getScheduleStatusColor(),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Column(
                    children: [
                      Text(
                        _scheduleStatus,
                        style: const TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                        ),
                        textAlign: TextAlign.center,
                      ),
                      if (_lastAlarmId != null) ...[
                        const SizedBox(height: 8),
                        Text(
                          'ID: $_lastAlarmId',
                          style: const TextStyle(
                            color: Colors.white70,
                            fontSize: 12,
                          ),
                          textAlign: TextAlign.center,
                        ),
                      ],
                    ],
                  ),
                ),
                const SizedBox(height: 20),
                ElevatedButton(
                  onPressed:
                      _authStatus == 'Granted' ? _scheduleTestAlarm : null,
                  child: const Text('Schedule Test Alarm (5s)'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Color _getStatusColor() {
    switch (_authStatus) {
      case 'Granted':
        return Colors.green;
      case 'Denied':
        return Colors.red;
      case 'Requesting...':
        return Colors.orange;
      case 'iOS 26.0+ required':
        return Colors.blue;
      default:
        return Colors.grey;
    }
  }

  Color _getScheduleStatusColor() {
    if (_scheduleStatus == 'Alarm scheduled!') {
      return Colors.green;
    } else if (_scheduleStatus == 'Scheduling...') {
      return Colors.orange;
    } else if (_scheduleStatus.startsWith('Error') ||
        _scheduleStatus == 'iOS 26.0+ required' ||
        _scheduleStatus == 'Please grant alarm permission first') {
      return Colors.red;
    } else {
      return Colors.grey;
    }
  }
}