torch_flashlight 0.0.3 copy "torch_flashlight: ^0.0.3" to clipboard
torch_flashlight: ^0.0.3 copied to clipboard

A Flutter plugin for controlling torch/flashlight availability, state, blinking, SOS, brightness, and background operation.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Torch Flashlight Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.amber),
        useMaterial3: true,
      ),
      home: const MainScreen(),
    );
  }
}

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

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  final TorchController _controller = TorchController();
  bool _isTorchOn = false;
  bool _isTorchAvailable = false;
  bool _isLoading = true;
  TorchCapabilities? _capabilities;
  FlashMode _selectedFlashMode = FlashMode.torch;
  int _strength = 0;
  int _maxStrength = 0;
  StreamSubscription<bool>? _torchStateSubscription;

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

  Future<void> _initializeTorch() async {
    final available = await _controller.isAvailable();
    final capabilities = await _controller.getCapabilities();
    final maxStrength = await _controller.getMaxStrength();

    setState(() {
      _isTorchAvailable = available;
      _capabilities = capabilities;
      _maxStrength = maxStrength;
      _isLoading = false;
    });

    // Listen to torch state changes
    _torchStateSubscription = _controller.torchStream.listen((isOn) {
      if (mounted) {
        setState(() {
          _isTorchOn = isOn;
        });
      }
    });
  }

  @override
  void dispose() {
    _torchStateSubscription?.cancel();
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Torch Flashlight Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : !_isTorchAvailable
              ? const Center(child: Text('No torch available on this device'))
              : SingleChildScrollView(
                  padding: const EdgeInsets.all(16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      _buildTorchStatusCard(),
                      const SizedBox(height: 16),
                      _buildCapabilitiesCard(),
                      const SizedBox(height: 16),
                      _buildBasicControlsCard(),
                      const SizedBox(height: 16),
                      _buildFlashModeCard(),
                      const SizedBox(height: 16),
                      _buildStrengthControlCard(),
                      const SizedBox(height: 16),
                      _buildBlinkingCard(),
                      const SizedBox(height: 16),
                      _buildSOSCard(),
                      const SizedBox(height: 16),
                      _buildFadeCard(),
                      const SizedBox(height: 16),
                      _buildBackgroundCard(),
                      const SizedBox(height: 16),
                      _buildNativeBlinkCard(),
                    ],
                  ),
                ),
    );
  }

  Widget _buildTorchStatusCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            Icon(
              _isTorchOn ? Icons.flashlight_on : Icons.flashlight_off,
              size: 80,
              color: _isTorchOn ? Colors.amber : Colors.grey,
            ),
            const SizedBox(height: 16),
            Text(
              _isTorchOn ? 'Torch is ON' : 'Torch is OFF',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: _toggleTorch,
              icon: Icon(_isTorchOn ? Icons.flash_off : Icons.flash_on),
              label: Text(_isTorchOn ? 'Turn Off' : 'Turn On'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
                backgroundColor: _isTorchOn ? Colors.red : Colors.green,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildCapabilitiesCard() {
    if (_capabilities == null) return const SizedBox.shrink();

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Device Capabilities',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            _buildCapabilityRow(
                'Strength Control', _capabilities!.supportsStrength),
            _buildCapabilityRow('Blinking', _capabilities!.supportsBlinking),
            _buildCapabilityRow(
                'Background Operation', _capabilities!.supportsBackground),
            _buildCapabilityRow('Fade Effects', _capabilities!.supportsFade),
            _buildCapabilityRow('SOS Mode', _capabilities!.supportsSOS),
            _buildCapabilityRow(
                'Custom Blink', _capabilities!.supportsCustomBlink),
          ],
        ),
      ),
    );
  }

  Widget _buildCapabilityRow(String label, bool supported) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        children: [
          Icon(
            supported ? Icons.check_circle : Icons.cancel,
            color: supported ? Colors.green : Colors.red,
            size: 20,
          ),
          const SizedBox(width: 8),
          Text(label),
        ],
      ),
    );
  }

  Widget _buildBasicControlsCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Basic Controls',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _enable,
                    icon: const Icon(Icons.play_arrow),
                    label: const Text('Enable'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _disable,
                    icon: const Icon(Icons.stop),
                    label: const Text('Disable'),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _toggle,
              icon: const Icon(Icons.swap_horiz),
              label: const Text('Toggle'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildFlashModeCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Flash Mode',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            SegmentedButton<FlashMode>(
              segments: const [
                ButtonSegment(
                  value: FlashMode.torch,
                  label: Text('Torch'),
                  icon: Icon(Icons.flashlight_on),
                ),
                ButtonSegment(
                  value: FlashMode.flash,
                  label: Text('Flash'),
                  icon: Icon(Icons.bolt),
                ),
              ],
              selected: {_selectedFlashMode},
              onSelectionChanged: (Set<FlashMode> newSelection) {
                setState(() {
                  _selectedFlashMode = newSelection.first;
                });
              },
            ),
            const SizedBox(height: 12),
            ElevatedButton.icon(
              onPressed: () => _enableWithMode(_selectedFlashMode),
              icon: const Icon(Icons.play_arrow),
              label: Text('Enable with ${_selectedFlashMode.name} mode'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildStrengthControlCard() {
    if (_capabilities == null || !_capabilities!.supportsStrength) {
      return const SizedBox.shrink();
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Strength Control',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            Text('Current: $_strength / Max: $_maxStrength'),
            const SizedBox(height: 12),
            Slider(
              value: _strength.toDouble(),
              max: _maxStrength.toDouble(),
              divisions: _maxStrength > 0 ? _maxStrength : 1,
              label: _strength.toString(),
              onChanged: (value) {
                setState(() {
                  _strength = value.toInt();
                });
              },
            ),
            const SizedBox(height: 12),
            ElevatedButton.icon(
              onPressed: () => _setStrength(_strength),
              icon: const Icon(Icons.tune),
              label: const Text('Set Strength'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBlinkingCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Blinking',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: () => _startBlinking(500),
                    icon: const Icon(Icons.play_arrow),
                    label: const Text('Blink 500ms'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: () => _startBlinking(1000),
                    icon: const Icon(Icons.play_arrow),
                    label: const Text('Blink 1s'),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _stopBlinking,
              icon: const Icon(Icons.stop),
              label: const Text('Stop Blinking'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
                backgroundColor: Colors.red,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSOSCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'SOS Mode',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            ElevatedButton.icon(
              onPressed: _startSOS,
              icon: const Icon(Icons.sos),
              label: const Text('Start SOS'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
                backgroundColor: Colors.orange,
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _stopSOS,
              icon: const Icon(Icons.stop),
              label: const Text('Stop SOS'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
                backgroundColor: Colors.red,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildFadeCard() {
    if (_capabilities == null || !_capabilities!.supportsFade) {
      return const SizedBox.shrink();
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Fade Effects',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _fadeIn,
                    icon: const Icon(Icons.arrow_upward),
                    label: const Text('Fade In'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _fadeOut,
                    icon: const Icon(Icons.arrow_downward),
                    label: const Text('Fade Out'),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBackgroundCard() {
    if (_capabilities == null || !_capabilities!.supportsBackground) {
      return const SizedBox.shrink();
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Background Execution',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            ElevatedButton.icon(
              onPressed: _startForegroundService,
              icon: const Icon(Icons.play_arrow),
              label: const Text('Start Foreground Service'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _stopForegroundService,
              icon: const Icon(Icons.stop),
              label: const Text('Stop Foreground Service'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
                backgroundColor: Colors.red,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildNativeBlinkCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Native Blinking (Better Performance)',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: () => _startNativeBlink(300),
                    icon: const Icon(Icons.play_arrow),
                    label: const Text('300ms'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: () => _startNativeBlink(500),
                    icon: const Icon(Icons.play_arrow),
                    label: const Text('500ms'),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _stopNativeBlink,
              icon: const Icon(Icons.stop),
              label: const Text('Stop Native Blink'),
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 48),
                backgroundColor: Colors.red,
              ),
            ),
          ],
        ),
      ),
    );
  }

  // Action methods
  Future<void> _toggleTorch() async {
    try {
      await _controller.toggle();
    } catch (e) {
      _showError('Failed to toggle torch: $e');
    }
  }

  Future<void> _enable() async {
    try {
      await _controller.enable();
    } catch (e) {
      _showError('Failed to enable torch: $e');
    }
  }

  Future<void> _disable() async {
    try {
      await _controller.disable();
    } catch (e) {
      _showError('Failed to disable torch: $e');
    }
  }

  Future<void> _toggle() async {
    try {
      await _controller.toggle();
    } catch (e) {
      _showError('Failed to toggle torch: $e');
    }
  }

  Future<void> _enableWithMode(FlashMode mode) async {
    try {
      await _controller.enable(mode: mode);
    } catch (e) {
      _showError('Failed to enable torch: $e');
    }
  }

  Future<void> _setStrength(int strength) async {
    try {
      await _controller.setStrength(strength);
      _showMessage('Strength set to $strength');
    } catch (e) {
      _showError('Failed to set strength: $e');
    }
  }

  Future<void> _startBlinking(int interval) async {
    try {
      // Use custom blink pattern for simple blinking
      final pattern = [interval, interval]; // on/off pattern
      await _controller.startCustomBlink(pattern);
      _showMessage('Blinking started (${interval}ms interval)');
    } catch (e) {
      _showError('Failed to start blinking: $e');
    }
  }

  Future<void> _stopBlinking() async {
    try {
      await _controller.stopCustomBlink();
      _showMessage('Blinking stopped');
    } catch (e) {
      _showError('Failed to stop blinking: $e');
    }
  }

  Future<void> _startSOS() async {
    try {
      await _controller.startSOS();
      _showMessage('SOS mode started');
    } catch (e) {
      _showError('Failed to start SOS: $e');
    }
  }

  Future<void> _stopSOS() async {
    try {
      await _controller.stopSOS();
      _showMessage('SOS mode stopped');
    } catch (e) {
      _showError('Failed to stop SOS: $e');
    }
  }

  Future<void> _fadeIn() async {
    try {
      await _controller.fadeIn();
      _showMessage('Fade in started');
    } catch (e) {
      _showError('Failed to fade in: $e');
    }
  }

  Future<void> _fadeOut() async {
    try {
      await _controller.fadeOut();
      _showMessage('Fade out started');
    } catch (e) {
      _showError('Failed to fade out: $e');
    }
  }

  Future<void> _startForegroundService() async {
    try {
      await _controller.startForegroundService();
      _showMessage('Foreground service started');
    } catch (e) {
      _showError('Failed to start foreground service: $e');
    }
  }

  Future<void> _stopForegroundService() async {
    try {
      await _controller.stopForegroundService();
      _showMessage('Foreground service stopped');
    } catch (e) {
      _showError('Failed to stop foreground service: $e');
    }
  }

  Future<void> _startNativeBlink(int interval) async {
    try {
      await _controller.startNativeBlink(interval);
      _showMessage('Native blinking started (${interval}ms interval)');
    } catch (e) {
      _showError('Failed to start native blinking: $e');
    }
  }

  Future<void> _stopNativeBlink() async {
    try {
      await _controller.stopNativeBlink();
      _showMessage('Native blinking stopped');
    } catch (e) {
      _showError('Failed to stop native blinking: $e');
    }
  }

  void _showMessage(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: Colors.green),
    );
  }

  void _showError(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: Colors.red),
    );
  }
}
6
likes
150
points
91
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for controlling torch/flashlight availability, state, blinking, SOS, brightness, and background operation.

Repository (GitHub)
View/report issues

Topics

#flashlight #torch #camera #blink #sos

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface

More

Packages that depend on torch_flashlight

Packages that implement torch_flashlight