Skip to main content

device_security_plus 1.0.7 copy "device_security_plus: ^1.0.7" to clipboard
device_security_plus: ^1.0.7 copied to clipboard

A Flutter plugin to retrieve unique device identifiers and monitor real-time security statuses (VPN, Debug Mode, USB Connection) across iOS and Android.

example/lib/main.dart

import 'package:device_security_plus/device_security.dart';
import 'package:flutter/material.dart';
import 'package:device_security_plus/device_security_snapshot.dart';

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

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

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

class _MyAppState extends State<MyApp> {
  final _deviceSecurityPlugin = DeviceSecurity();

  // State for the one-time snapshot
  DeviceSecuritySnapshot? _snapshot;
  bool _isLoadingSnapshot = false;

  // Streams for live monitoring
  late final Stream<bool?> _usbStream;
  late final Stream<bool?> _debugStream;
  late final Stream<bool?> _vpnStream;
  late final Stream<Map<SecurityStatus, bool>> _combinedStream;

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

    // 1. Initialize live streams
    _usbStream = _deviceSecurityPlugin.getUsbConnectedStatus();
    _debugStream = _deviceSecurityPlugin.getDebugModeStatus();
    _vpnStream = _deviceSecurityPlugin.getVpnConnectionStatus();
    _combinedStream = _deviceSecurityPlugin.getSecurityStatusStream();

    // 2. Fetch initial snapshot
    _fetchSnapshot();
  }

  Future<void> _fetchSnapshot() async {
    setState(() => _isLoadingSnapshot = true);
    try {
      final snapshot = await _deviceSecurityPlugin.getSecuritySnapshot();
      if (mounted) {
        setState(() => _snapshot = snapshot);
      }
    } catch (e) {
      debugPrint("Error fetching snapshot: $e");
    } finally {
      if (mounted) {
        setState(() => _isLoadingSnapshot = false);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blueGrey),
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Device Security Example'),
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        ),
        body: SingleChildScrollView(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _buildSnapshotCard(),
              const SizedBox(height: 24),
              _buildLiveMonitoringCard(),
              const SizedBox(height: 24),
              _buildCombinedStreamCard(),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildSnapshotCard() {
    return Card(
      elevation: 4,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  '1. Startup Snapshot',
                  style: Theme.of(context).textTheme.titleLarge,
                ),
                IconButton(
                  icon: const Icon(Icons.refresh),
                  onPressed: _isLoadingSnapshot ? null : _fetchSnapshot,
                  tooltip: 'Refresh Snapshot',
                ),
              ],
            ),
            const Text(
              'A one-time check, perfect for app launch.',
              style: TextStyle(color: Colors.grey),
            ),
            const Divider(),
            if (_isLoadingSnapshot)
              const Padding(
                padding: EdgeInsets.all(16.0),
                child: Center(child: CircularProgressIndicator()),
              )
            else if (_snapshot != null) ...[
              _buildStatusRow(
                'Device ID',
                _snapshot!.deviceId ?? 'Unknown',
                Icons.perm_device_information,
              ),
              _buildStatusRow(
                'USB Connected',
                _snapshot!.isUsbConnected.toString(),
                Icons.usb,
              ),
              _buildStatusRow(
                'Debug Mode',
                _snapshot!.isDebugMode.toString(),
                Icons.bug_report,
              ),
              _buildStatusRow(
                'VPN Connected',
                _snapshot!.isVpnConnected.toString(),
                Icons.vpn_lock,
              ),
            ] else
              const Text('Failed to load snapshot.'),
          ],
        ),
      ),
    );
  }

  Widget _buildLiveMonitoringCard() {
    return Card(
      elevation: 4,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '2. Live Monitoring',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const Text(
              'Continuous streams that react instantly to changes.',
              style: TextStyle(color: Colors.grey),
            ),
            const Divider(),
            _buildLiveStreamRow('USB Connected', _usbStream, Icons.usb),
            _buildLiveStreamRow('Debug Mode', _debugStream, Icons.bug_report),
            _buildLiveStreamRow('VPN Connected', _vpnStream, Icons.vpn_lock),
          ],
        ),
      ),
    );
  }

  Widget _buildCombinedStreamCard() {
    return Card(
      elevation: 4,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '3. Combined Live Monitoring',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const Text(
              'A single stream returning a map of all security statuses.',
              style: TextStyle(color: Colors.grey),
            ),
            const Divider(),
            StreamBuilder<Map<SecurityStatus, bool>>(
              stream: _combinedStream,
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return const Padding(
                    padding: EdgeInsets.all(16.0),
                    child: Center(child: CircularProgressIndicator()),
                  );
                }
                final statuses = snapshot.data!;
                return Column(
                  children: [
                    _buildStatusRow(
                      'USB Connected',
                      statuses[SecurityStatus.usbConnection].toString(),
                      Icons.usb,
                      isLive: true,
                    ),
                    _buildStatusRow(
                      'Debug Mode',
                      statuses[SecurityStatus.debugMode].toString(),
                      Icons.bug_report,
                      isLive: true,
                    ),
                    _buildStatusRow(
                      'VPN Connected',
                      statuses[SecurityStatus.vpnConnection].toString(),
                      Icons.vpn_lock,
                      isLive: true,
                    ),
                  ],
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildLiveStreamRow(
    String title,
    Stream<bool?> stream,
    IconData icon,
  ) {
    return StreamBuilder<bool?>(
      stream: stream,
      builder: (context, snapshot) {
        final value = snapshot.hasData
            ? snapshot.data.toString()
            : 'Waiting...';
        return _buildStatusRow(title, value, icon, isLive: true);
      },
    );
  }

  Widget _buildStatusRow(
    String label,
    String value,
    IconData icon, {
    bool isLive = false,
  }) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: Row(
        children: [
          Icon(icon, size: 24, color: isLive ? Colors.blue : Colors.black54),
          const SizedBox(width: 12),
          Expanded(
            child: Text(
              label,
              style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
          ),
          Text(
            value,
            style: TextStyle(
              fontSize: 16,
              // Highlights 'true' (usually bad for security) in red, 'false' in green.
              color: value == 'true'
                  ? Colors.red
                  : (value == 'false' ? Colors.green : Colors.grey),
              fontWeight: FontWeight.w500,
            ),
          ),
        ],
      ),
    );
  }
}
2
likes
160
points
264
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin to retrieve unique device identifiers and monitor real-time security statuses (VPN, Debug Mode, USB Connection) across iOS and Android.

Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

device_info_plus, flutter, flutter_secure_storage, plugin_platform_interface, uuid

More

Packages that depend on device_security_plus

Packages that implement device_security_plus