mobile_signal 0.0.1 copy "mobile_signal: ^0.0.1" to clipboard
mobile_signal: ^0.0.1 copied to clipboard

Check mobile signal strength.

example/lib/main.dart

import 'dart:async';

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

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

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

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: 'Mobile Signal Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
          useMaterial3: true,
        ),
        home: const SignalMonitorPage(),
      );
}

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

  @override
  State<SignalMonitorPage> createState() => _SignalMonitorPageState();
}

class _SignalMonitorPageState extends State<SignalMonitorPage> {
  SignalData? _lastSignal;
  bool _isMonitoring = false;
  String _error = '';
  StreamSubscription<SignalData>? _signalSubscription;

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

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

  Future<void> _checkPermissionAndStartMonitoring() async {
    bool isGranted = await MobileSignal.instance.checkPermissions();
    if (!isGranted) {
      isGranted = await _requestPermissions();
    }
    if (isGranted) {
      _startMonitoring();
    } else {
      setState(() {
        _error = 'Permissions are required to access phone status.';
      });
    }
  }

  Future<bool> _requestPermissions() async {
    final hasPermission = await MobileSignal.instance.requestPermissions();

    return hasPermission;
  }

  Future<void> _startMonitoring() async {
    try {
      await MobileSignal.instance.startBackgroundService(
        showNotificationTitle: true,
        showNotificationValues: true,
        notificationChannelName: 'Notification channel',
        notificationTitle: 'Mobile Signal',
        notificationDescription: 'Active Monitor',
      );

      _signalSubscription = MobileSignal.instance.signalStream.listen(
        (signal) {
          setState(() {
            _lastSignal = signal;
            _isMonitoring = true;
            _error = '';
          });
        },
        onError: (error) {
          setState(() {
            _error = 'Error: $error';
            _isMonitoring = false;
          });
        },
      );
    } catch (e) {
      setState(() {
        _error = 'Error starting monitoring: $e';
        _isMonitoring = false;
      });
    }
  }

  Future<void> _stopMonitoring() async {
    try {
      await _signalSubscription?.cancel();
      _signalSubscription = null;

      await MobileSignal.instance.stopBackgroundService();

      setState(() {
        _isMonitoring = false;
        _lastSignal = null;
      });
    } catch (e) {
      setState(() {
        _error = 'Error stopping monitoring: $e';
      });
    }
  }

  String _getFormattedTimestamp(int timestamp) {
    try {
      final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
      return '${date.hour.toString().padLeft(2, '0')}:'
          '${date.minute.toString().padLeft(2, '0')}:'
          '${date.second.toString().padLeft(2, '0')}';
    } catch (e) {
      return 'Invalid timestamp';
    }
  }

  Widget _buildSignalIndicator(int level) => Container(
        width: 140,
        padding: const EdgeInsets.all(8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.end,
          mainAxisSize: MainAxisSize.min,
          children: List.generate(
              4,
              (index) => Container(
                    width: 8,
                    height: 12 + (index * 4),
                    margin:
                        const EdgeInsets.symmetric(horizontal: 1, vertical: 2),
                    decoration: BoxDecoration(
                      color: index < level ? Colors.blue : Colors.grey.shade300,
                      borderRadius: BorderRadius.circular(2),
                    ),
                  )),
        ),
      );

  Widget _buildMetricCard(String title, String value, {String? subtitle}) =>
      SizedBox(
        width: 140,
        child: Card(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                Text(
                  title,
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.grey.shade600,
                  ),
                ),
                const SizedBox(height: 8),
                Text(
                  value,
                  style: const TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                if (subtitle != null) ...[
                  const SizedBox(height: 4),
                  Text(
                    subtitle,
                    style: TextStyle(
                      fontSize: 12,
                      color: Colors.grey.shade600,
                    ),
                  ),
                ],
              ],
            ),
          ),
        ),
      );

  Widget _buildSignalInfo() {
    if (!_isMonitoring) {
      return const SizedBox.shrink();
    }

    if (_lastSignal == null && _isMonitoring) {
      return const Card(
        child: Padding(
          padding: EdgeInsets.all(16),
          child: Text(
            'Waiting for signal data...',
            textAlign: TextAlign.center,
          ),
        ),
      );
    }

    return Column(
      children: [
        Row(
          children: [
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  children: [
                    _buildSignalIndicator(_lastSignal!.level),
                    Text(
                      'Last update: ${_getFormattedTimestamp(_lastSignal!.ts)}',
                      style: Theme.of(context).textTheme.bodySmall,
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(width: 16),
            _buildNetworkInfo('Network', _lastSignal?.network),
          ],
        ),
        const SizedBox(height: 16),
        Row(
          children: [
            Expanded(
              child: _buildMetricCard(
                'Signal strength',
                '${_lastSignal!.dbm}',
                subtitle: 'dBm',
              ),
            ),
            const SizedBox(width: 16),
            Expanded(
              child: _buildMetricCard(
                'ASU Level',
                '${_lastSignal!.asu}',
                subtitle: 'Arbitrary Strength Unit',
              ),
            ),
          ],
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Mobile Signal Monitor'),
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          actions: [
            IconButton(
              icon: Icon(_isMonitoring ? Icons.stop : Icons.play_arrow),
              onPressed: _isMonitoring ? _stopMonitoring : _startMonitoring,
            ),
          ],
        ),
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                if (_error.isNotEmpty)
                  Card(
                    color: Colors.red.shade100,
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Row(
                        children: [
                          Icon(Icons.error_outline, color: Colors.red.shade700),
                          const SizedBox(width: 8),
                          Expanded(
                            child: Text(
                              _error,
                              style: TextStyle(color: Colors.red.shade700),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                const SizedBox(height: 16),
                _buildSignalInfo(),
                const Spacer(),
                ElevatedButton.icon(
                  onPressed: _isMonitoring ? _stopMonitoring : _startMonitoring,
                  icon: Icon(_isMonitoring ? Icons.stop : Icons.play_arrow),
                  label: Text(
                      _isMonitoring ? 'Stop Monitoring' : 'Start Monitoring'),
                ),
              ],
            ),
          ),
        ),
      );

  Widget _buildNetworkInfo(String title, String? value) => Card(
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: SizedBox(
            width: 140,
            child: Column(
              children: [
                Text(
                  title,
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.grey.shade600,
                  ),
                ),
                const SizedBox(height: 8),
                Text(
                  value ?? 'N/A',
                  style: const TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  'isAirplane: ${_lastSignal?.isAirplane ?? false}',
                  style: TextStyle(
                    fontSize: 12,
                    color: Colors.grey.shade600,
                  ),
                ),
              ],
            ),
          ),
        ),
      );
}
0
likes
0
points
319
downloads

Publisher

unverified uploader

Weekly Downloads

Check mobile signal strength.

Homepage
View/report issues

License

unknown (license)

Dependencies

equatable, flutter, plugin_platform_interface

More

Packages that depend on mobile_signal