nexora_sdk 3.4.4 copy "nexora_sdk: ^3.4.4" to clipboard
nexora_sdk: ^3.4.4 copied to clipboard

A cross-platform Flutter hardware SDK with native Android/iOS hardware APIs plus safe web and desktop fallbacks.

example/lib/main.dart

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

void main() {
  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: IntelligenceDashboard(),
    ),
  );
}

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

  @override
  State<IntelligenceDashboard> createState() => _IntelligenceDashboardState();
}

class _IntelligenceDashboardState extends State<IntelligenceDashboard> {
  final _sdk = NexoraSdk.instance;

  StreamSubscription? _cameraSub;
  StreamSubscription? _audioSub;
  StreamSubscription? _locationSub;

  int? _textureId;
  bool _isCameraRunning = false;
  bool _isVisionFace = false;
  bool _isVisionBarcode = false;
  bool _isAudioRunning = false;
  bool _isLogging = false;

  List<double> _audioSpectrum = [];
  int _faceCount = 0;
  String _lastBarcode = "None";
  LocationData? _currentLocation;
  BatteryInfo? _batteryInfo;
  StorageInfo? _storageInfo;
  DeviceInfo? _deviceInfo;
  ConnectivityInfo? _connectivityInfo;
  HardwarePermissionSnapshot? _permissionSnapshot;
  HardwareLifecycleController? _lifecycleController;
  String _lastNativeAction = "Ready";
  List<FileInfo> _files = [];
  Timer? _healthTimer;

  @override
  void initState() {
    super.initState();
    _lifecycleController = _sdk.attachLifecycleController(stopLogging: false);
    _requestAllPermissions();
    _startPeriodicHealthCheck();
  }

  Future<void> _requestAllPermissions() async {
    await _sdk.requestPermissions();
    _setupListeners();
    _loadStorageInfo();
    _loadProInfo();
  }

  void _setupListeners() {
    _cameraSub = _sdk.camera.stream.listen((frame) {
      if (!mounted) return;
      setState(() {
        if (frame.vision != null) {
          _faceCount = frame.vision!.faces.length;
          if (frame.vision!.barcodes.isNotEmpty) {
            _lastBarcode = frame.vision!.barcodes.first;
          }
        }
      });
    });

    _audioSub = _sdk.audio.stream.listen((frame) {
      if (!mounted || !_isAudioRunning) return;
      setState(() {
        _audioSpectrum = frame.spectrum;
      });
    });

    _locationSub = _sdk.location.stream.listen((loc) {
      if (!mounted) return;
      setState(() {
        _currentLocation = loc;
      });
    });
  }

  void _startPeriodicHealthCheck() {
    _healthTimer = Timer.periodic(const Duration(seconds: 5), (timer) async {
      final info = await _sdk.health.getBatteryInfo();
      if (mounted) {
        setState(() {
          _batteryInfo = info;
        });
      }
    });
  }

  Future<void> _loadStorageInfo() async {
    final info = await _sdk.storage.getStorageInfo();
    final files = await _sdk.storage.listFiles();
    if (mounted) {
      setState(() {
        _storageInfo = info;
        _files = files;
      });
    }
  }

  Future<void> _loadProInfo() async {
    final device = await _sdk.device.getInfo();
    final connectivity = await _sdk.connectivity.getInfo();
    final permissions = await _sdk.getPermissionSnapshot();
    if (mounted) {
      setState(() {
        _deviceInfo = device;
        _connectivityInfo = connectivity;
        _permissionSnapshot = permissions;
      });
    }
  }

  @override
  void dispose() {
    _cameraSub?.cancel();
    _audioSub?.cancel();
    _locationSub?.cancel();
    _healthTimer?.cancel();
    _lifecycleController?.dispose();
    _sdk.camera.stop();
    _sdk.audio.stop();
    _sdk.location.stop();
    super.dispose();
  }

  void _toggleCamera() async {
    if (_isCameraRunning) {
      await _sdk.camera.stop();
      setState(() {
        _isCameraRunning = false;
        _textureId = null;
      });
    } else {
      final id = await _sdk.camera.start();
      setState(() {
        _isCameraRunning = true;
        _textureId = id;
      });
    }
  }

  void _toggleVision(String type) async {
    if (type == 'face') _isVisionFace = !_isVisionFace;
    if (type == 'barcode') _isVisionBarcode = !_isVisionBarcode;
    await _sdk.setVisionMode(face: _isVisionFace, barcode: _isVisionBarcode);
    setState(() {});
  }

  void _toggleLogging() async {
    if (_isLogging) {
      await _sdk.stopLogging();
      setState(() => _isLogging = false);
    } else {
      await _sdk.startLogging(LogConfig(fileName: "nexora_telemetry.csv"));
      setState(() => _isLogging = true);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0F172A),
      body: CustomScrollView(
        slivers: [
          _buildAppBar(),
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                children: [
                  _buildQuickStats(),
                  const SizedBox(height: 20),
                  _buildCameraCard(),
                  const SizedBox(height: 20),
                  _buildAudioCard(),
                  const SizedBox(height: 20),
                  _buildLocationCard(),
                  const SizedBox(height: 20),
                  _buildStorageCard(),
                  const SizedBox(height: 20),
                  _buildProCard(),
                  const SizedBox(height: 20),
                  _buildAdvancedFeaturesCard(),
                  const SizedBox(height: 20),
                  _buildLoggingCard(),
                  const SizedBox(height: 40),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildAppBar() {
    return SliverAppBar(
      expandedHeight: 120,
      pinned: true,
      backgroundColor: const Color(0xFF1E293B),
      flexibleSpace: FlexibleSpaceBar(
        title: const Text(
          "NEXORA INTELLIGENCE",
          style: TextStyle(
            letterSpacing: 2,
            fontWeight: FontWeight.bold,
            fontSize: 16,
          ),
        ),
        background: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.blue.shade900, Colors.black],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildQuickStats() {
    return Row(
      children: [
        _buildStatItem("Faces", "$_faceCount", Icons.face, Colors.orange),
        const SizedBox(width: 12),
        _buildStatItem(
          "Battery",
          "${_batteryInfo?.level.toInt() ?? '--'}%",
          Icons.battery_charging_full,
          Colors.green,
        ),
        const SizedBox(width: 12),
        _buildStatItem(
          "Storage",
          _storageInfo?.internalFreeFormatted ?? '--',
          Icons.sd_storage,
          Colors.purple,
        ),
      ],
    );
  }

  Widget _buildStatItem(
    String label,
    String value,
    IconData icon,
    Color color,
  ) {
    return Expanded(
      child: Container(
        padding: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: const Color(0xFF1E293B),
          borderRadius: BorderRadius.circular(16),
        ),
        child: Column(
          children: [
            Icon(icon, color: color, size: 20),
            const SizedBox(height: 8),
            Text(
              value,
              style: const TextStyle(
                color: Colors.white,
                fontSize: 16,
                fontWeight: FontWeight.bold,
              ),
            ),
            Text(
              label,
              style: const TextStyle(color: Colors.white54, fontSize: 10),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildCameraCard() {
    return _buildDashboardCard(
      title: "Vision AI Control",
      icon: Icons.auto_awesome,
      child: Column(
        children: [
          Container(
            height: 250,
            width: double.infinity,
            decoration: BoxDecoration(
              color: Colors.black,
              borderRadius: BorderRadius.circular(12),
            ),
            child: _textureId != null
                ? ClipRRect(
                    borderRadius: BorderRadius.circular(12),
                    child: Texture(textureId: _textureId!),
                  )
                : const Center(
                    child: Icon(
                      Icons.videocam_off,
                      color: Colors.white24,
                      size: 48,
                    ),
                  ),
          ),
          const SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              _buildToggleButton(
                "FACE",
                _isVisionFace,
                () => _toggleVision('face'),
              ),
              _buildToggleButton(
                "BARCODE",
                _isVisionBarcode,
                () => _toggleVision('barcode'),
              ),
              ElevatedButton(
                onPressed: _toggleCamera,
                style: ElevatedButton.styleFrom(
                  backgroundColor: _isCameraRunning ? Colors.red : Colors.blue,
                ),
                child: Text(_isCameraRunning ? "STOP" : "START"),
              ),
            ],
          ),
          const SizedBox(height: 12),
          Row(
            children: [
              Expanded(
                child: ElevatedButton.icon(
                  onPressed: _isCameraRunning
                      ? () async {
                          final path = await _sdk.camera.takePhoto();
                          if (mounted) {
                            setState(
                              () => _lastNativeAction = path ?? "Photo failed",
                            );
                          }
                        }
                      : null,
                  icon: const Icon(Icons.photo_camera),
                  label: const Text("PHOTO"),
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: ElevatedButton.icon(
                  onPressed: () async {
                    await _sdk.native.shareText("Nexora SDK hardware demo");
                  },
                  icon: const Icon(Icons.ios_share),
                  label: const Text("SHARE"),
                ),
              ),
            ],
          ),
          if (_isVisionBarcode)
            Padding(
              padding: const EdgeInsets.only(top: 12),
              child: Text(
                "Last Barcode: $_lastBarcode",
                style: const TextStyle(color: Colors.cyanAccent, fontSize: 12),
              ),
            ),
        ],
      ),
    );
  }

  Widget _buildAudioCard() {
    return _buildDashboardCard(
      title: "Audio FFT Visualizer",
      icon: Icons.graphic_eq,
      child: Column(
        children: [
          SizedBox(
            height: 80,
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: _audioSpectrum.isEmpty
                  ? [
                      const Expanded(
                        child: Center(
                          child: Text(
                            "Start Audio to see FFT",
                            style: TextStyle(color: Colors.white24),
                          ),
                        ),
                      ),
                    ]
                  : _audioSpectrum
                        .take(40)
                        .map(
                          (v) => Expanded(
                            child: Container(
                              margin: const EdgeInsets.symmetric(horizontal: 1),
                              height: (v * 100).clamp(2.0, 80.0),
                              color: Colors.cyanAccent,
                            ),
                          ),
                        )
                        .toList(),
            ),
          ),
          const SizedBox(height: 16),
          _buildToggleButton("REAL-TIME FFT", _isAudioRunning, () async {
            if (_isAudioRunning) {
              await _sdk.audio.stop();
              setState(() => _isAudioRunning = false);
            } else {
              await _sdk.startAudioWithAnalysis();
              setState(() => _isAudioRunning = true);
            }
          }),
        ],
      ),
    );
  }

  Widget _buildLocationCard() {
    return _buildDashboardCard(
      title: "Geospatial Data",
      icon: Icons.location_on,
      child: Column(
        children: [
          _buildDataRow(
            "Lat",
            _currentLocation?.latitude.toStringAsFixed(5) ?? '--',
          ),
          _buildDataRow(
            "Lon",
            _currentLocation?.longitude.toStringAsFixed(5) ?? '--',
          ),
          _buildDataRow(
            "Alt",
            "${_currentLocation?.altitude.toStringAsFixed(2) ?? '--'} m",
          ),
          const SizedBox(height: 12),
          ElevatedButton(
            onPressed: () => _sdk.location.start(),
            child: const Text("START GPS UPDATES"),
          ),
        ],
      ),
    );
  }

  Widget _buildStorageCard() {
    return _buildDashboardCard(
      title: "Device Storage",
      icon: Icons.sd_storage,
      child: Column(
        children: [
          if (_storageInfo != null) ...[
            // Storage usage bar
            ClipRRect(
              borderRadius: BorderRadius.circular(8),
              child: LinearProgressIndicator(
                value: _storageInfo!.internalUsage,
                minHeight: 8,
                backgroundColor: Colors.white10,
                valueColor: AlwaysStoppedAnimation(
                  _storageInfo!.internalUsage > 0.9 ? Colors.red : Colors.blue,
                ),
              ),
            ),
            const SizedBox(height: 12),
            _buildDataRow("Total", _storageInfo!.internalTotalFormatted),
            _buildDataRow("Free", _storageInfo!.internalFreeFormatted),
            _buildDataRow(
              "App Cache",
              StorageInfo.formatBytes(_storageInfo!.appCacheSize),
            ),
            _buildDataRow(
              "App Data",
              StorageInfo.formatBytes(_storageInfo!.appDataSize),
            ),
          ] else
            const Text("Loading...", style: TextStyle(color: Colors.white24)),
          const SizedBox(height: 12),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              _buildToggleButton("WRITE TEST", false, () async {
                await _sdk.storage.writeFile(
                  "test_note.txt",
                  "Hello from Nexora SDK! ${DateTime.now()}",
                );
                _loadStorageInfo();
              }),
              _buildToggleButton("READ TEST", false, () async {
                final content = await _sdk.storage.readFile("test_note.txt");
                if (mounted) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(content ?? "File not found"),
                      behavior: SnackBarBehavior.floating,
                    ),
                  );
                }
              }),
              _buildToggleButton("CLEAR CACHE", false, () async {
                await _sdk.storage.clearCache();
                _loadStorageInfo();
              }),
            ],
          ),
          if (_files.isNotEmpty) ...[
            const SizedBox(height: 12),
            const Align(
              alignment: Alignment.centerLeft,
              child: Text(
                "App Files:",
                style: TextStyle(color: Colors.white54, fontSize: 11),
              ),
            ),
            const SizedBox(height: 4),
            ...(_files
                .take(5)
                .map(
                  (f) => Padding(
                    padding: const EdgeInsets.symmetric(vertical: 2),
                    child: Row(
                      children: [
                        Icon(
                          f.isDirectory
                              ? Icons.folder
                              : Icons.insert_drive_file,
                          color: Colors.white24,
                          size: 14,
                        ),
                        const SizedBox(width: 8),
                        Expanded(
                          child: Text(
                            f.name,
                            style: const TextStyle(
                              color: Colors.white70,
                              fontSize: 11,
                            ),
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        Text(
                          f.sizeFormatted,
                          style: const TextStyle(
                            color: Colors.white38,
                            fontSize: 10,
                          ),
                        ),
                      ],
                    ),
                  ),
                )),
          ],
        ],
      ),
    );
  }

  Widget _buildLoggingCard() {
    return _buildDashboardCard(
      title: "Diagnostics & Telemetry",
      icon: Icons.terminal,
      child: ListTile(
        title: const Text(
          "Background CSV Logging",
          style: TextStyle(color: Colors.white),
        ),
        subtitle: const Text(
          "Records battery & wifi every 1s",
          style: TextStyle(color: Colors.white54, fontSize: 11),
        ),
        trailing: Switch(value: _isLogging, onChanged: (_) => _toggleLogging()),
      ),
    );
  }

  Widget _buildProCard() {
    return _buildDashboardCard(
      title: "Native Pro Layer",
      icon: Icons.settings_input_component,
      child: Column(
        children: [
          _buildDataRow("Device", _deviceInfo?.model ?? '--'),
          _buildDataRow("CPU", _deviceInfo?.cpuArchitecture ?? '--'),
          _buildDataRow(
            "Network",
            "${_connectivityInfo?.networkType ?? '--'} ${_connectivityInfo?.isMetered == true ? '(metered)' : ''}",
          ),
          _buildDataRow(
            "Permissions",
            _permissionSnapshot?.allGranted == true
                ? "Granted"
                : "Needs review",
          ),
          _buildDataRow("Last Action", _lastNativeAction),
          const SizedBox(height: 12),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              _buildToggleButton("REFRESH", false, _loadProInfo),
              _buildToggleButton("COPY", false, () async {
                await _sdk.native.copyText("Copied from Nexora SDK");
                setState(() => _lastNativeAction = "Copied text");
              }),
              _buildToggleButton("OPEN SETTINGS", false, () async {
                await _sdk.openAppSettings();
              }),
              _buildToggleButton("OPEN WEB", false, () async {
                await _sdk.native.openUrl("https://flutter.dev");
              }),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildAdvancedFeaturesCard() {
    return _buildDashboardCard(
      title: "Advanced Pro Capabilities",
      icon: Icons.offline_bolt,
      child: Column(
        children: [
          const Align(
            alignment: Alignment.centerLeft,
            child: Text(
              "Demonstrates the new stream buffering/throttling utilities, exponential backoff hardware retries, and versioned storage migration engines.",
              style: TextStyle(color: Colors.white70, fontSize: 12),
            ),
          ),
          const SizedBox(height: 12),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              _buildToggleButton("RUN STORAGE MIGRATION", false, () async {
                setState(() => _lastNativeAction = "Migrating Storage...");
                try {
                  await _sdk.storage.migrateStorage(1, 2, (newVer) async {
                    // Perform dummy storage migration logic
                    await _sdk.storage.writeFile(
                      "migrated_config.json",
                      '{"migrated": true, "version": $newVer}',
                    );
                  });
                  setState(
                    () => _lastNativeAction = "Migration finished successfully",
                  );
                  _loadStorageInfo();
                } catch (e) {
                  setState(() => _lastNativeAction = "Migration error: $e");
                }
              }),
            ],
          ),
          const SizedBox(height: 8),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              _buildToggleButton("DEMO STREAM UTILS", false, () async {
                setState(
                  () => _lastNativeAction =
                      "Simulating stream buffer/throttle...",
                );
                // Stream throttle example: throttle standard Stream
                final stream = Stream.periodic(
                  const Duration(milliseconds: 100),
                  (i) => i,
                ).take(10);
                final throttled = stream.throttle(
                  const Duration(milliseconds: 500),
                );
                // Just log to verify the stream utility exists and operates
                final values = await throttled.toList();
                setState(() => _lastNativeAction = "Stream throttled: $values");
              }),
              _buildToggleButton("DEMO RETRY HELPER", false, () async {
                setState(
                  () => _lastNativeAction = "Simulating retry connection...",
                );
                int attempts = 0;
                final result = await withRetry(
                  () async {
                    attempts++;
                    if (attempts < 3) {
                      throw const HardwareException(
                        code: HardwareErrorCode.deviceBusy,
                        message: "Simulating busy device connection",
                      );
                    }
                    return "Success after $attempts attempts";
                  },
                  maxAttempts: 3,
                  initialDelay: const Duration(milliseconds: 200),
                );
                setState(() => _lastNativeAction = result);
              }),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildDashboardCard({
    required String title,
    required IconData icon,
    required Widget child,
  }) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: const Color(0xFF1E293B),
        borderRadius: BorderRadius.circular(24),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Icon(icon, color: Colors.blue, size: 20),
              const SizedBox(width: 8),
              Text(
                title,
                style: const TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
          const Divider(color: Colors.white10, height: 24),
          child,
        ],
      ),
    );
  }

  Widget _buildDataRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(label, style: const TextStyle(color: Colors.white54)),
          Text(
            value,
            style: const TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.bold,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildToggleButton(String label, bool active, VoidCallback onTap) {
    return InkWell(
      onTap: onTap,
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
        decoration: BoxDecoration(
          color: active ? Colors.blue : Colors.white10,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Text(
          label,
          style: TextStyle(
            color: active ? Colors.white : Colors.white54,
            fontSize: 11,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  }
}
3
likes
135
points
537
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A cross-platform Flutter hardware SDK with native Android/iOS hardware APIs plus safe web and desktop fallbacks.

Repository (GitHub)
View/report issues
Contributing

Topics

#hardware #camera #bluetooth #sensors #cross-platform

License

MIT (license)

Dependencies

flutter, meta, nexora_sdk_android, nexora_sdk_desktop, nexora_sdk_ios, nexora_sdk_platform_interface, nexora_sdk_web

More

Packages that depend on nexora_sdk

Packages that implement nexora_sdk