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

A high-performance Flutter SDK providing native-level hardware access (Camera, Bluetooth, GPS) with responsive UI system and zero-lag architecture.

example/lib/main.dart

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

void main() {
  HardwarePlugin.initialise();
  runApp(const HardwareExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hardware SDK Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF6C63FF),
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
        fontFamily: 'monospace',
      ),
      home: const DashboardPage(),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// DASHBOARD
// ─────────────────────────────────────────────────────────────────────────────

class DashboardPage extends StatefulWidget {
  const DashboardPage({super.key});
  @override
  State<DashboardPage> createState() => _DashboardPageState();
}

class _DashboardPageState extends State<DashboardPage> {
  // ── BLE State ─────────────────────────────────────────
  bool _bleScanning = false;
  final List<BluetoothDevice> _devices = [];
  StreamSubscription<BluetoothDevice>? _bleSub;

  // ── GPS State ─────────────────────────────────────────
  bool _gpsRunning = false;
  GpsLocation? _lastLocation;
  StreamSubscription<GpsLocation>? _gpsSub;

  // ── Sensor State ──────────────────────────────────────
  bool _sensorsRunning = false;
  SensorSample? _lastSample;
  StreamSubscription<SensorSample>? _sensorSub;

  // ── Camera State ──────────────────────────────────────
  bool _cameraRunning = false;
  int _frameCount = 0;
  int _frameBytes = 0;
  StreamSubscription<CameraFrame>? _cameraSub;

  // ── WiFi ──────────────────────────────────────────────
  WifiInfo? _wifi;

  // ── Error ─────────────────────────────────────────────
  String? _errorMsg;

  @override
  void dispose() {
    _bleSub?.cancel();
    _gpsSub?.cancel();
    _sensorSub?.cancel();
    _cameraSub?.cancel();
    super.dispose();
  }

  void _showError(Object e) {
    setState(() => _errorMsg = e.toString());
  }

  // ── Actions ───────────────────────────────────────────

  Future<void> _toggleBle() async {
    setState(() => _errorMsg = null);
    try {
      if (_bleScanning) {
        await HardwarePlugin.bluetooth.stopScan();
        await _bleSub?.cancel();
        setState(() { _bleScanning = false; });
      } else {
        _devices.clear();
        await HardwarePlugin.bluetooth.startScan(timeout: const Duration(seconds: 15));
        _bleSub = HardwarePlugin.bluetooth.deviceStream.listen((d) {
          if (!_devices.any((x) => x.id == d.id)) {
            setState(() => _devices.add(d));
          }
        });
        setState(() => _bleScanning = true);
      }
    } catch (e) { _showError(e); }
  }

  Future<void> _toggleGps() async {
    setState(() => _errorMsg = null);
    try {
      if (_gpsRunning) {
        await HardwarePlugin.gps.stop();
        await _gpsSub?.cancel();
        setState(() => _gpsRunning = false);
      } else {
        await HardwarePlugin.gps.start(config: const GpsConfig(
          accuracy: GpsAccuracy.high,
          intervalMs: 1000,
        ));
        _gpsSub = HardwarePlugin.gps.locationStream.listen((loc) {
          setState(() => _lastLocation = loc);
        });
        setState(() => _gpsRunning = true);
      }
    } catch (e) { _showError(e); }
  }

  Future<void> _toggleSensors() async {
    setState(() => _errorMsg = null);
    try {
      if (_sensorsRunning) {
        await HardwarePlugin.sensors.stop();
        await _sensorSub?.cancel();
        setState(() => _sensorsRunning = false);
      } else {
        await HardwarePlugin.sensors.start(config: const SensorConfig(
          type: SensorType.accelerometer,
          samplingRateHz: 60,
        ));
        _sensorSub = HardwarePlugin.sensors.sampleStream.listen((s) {
          setState(() => _lastSample = s);
        });
        setState(() => _sensorsRunning = true);
      }
    } catch (e) { _showError(e); }
  }

  Future<void> _toggleCamera() async {
    setState(() => _errorMsg = null);
    try {
      if (_cameraRunning) {
        await HardwarePlugin.camera.stop();
        await _cameraSub?.cancel();
        setState(() { _cameraRunning = false; _frameCount = 0; });
      } else {
        await HardwarePlugin.camera.start();
        _cameraSub = HardwarePlugin.camera.frameStream.listen((f) {
          setState(() { _frameCount++; _frameBytes = f.sizeBytes; });
        });
        setState(() => _cameraRunning = true);
      }
    } catch (e) { _showError(e); }
  }

  Future<void> _loadWifi() async {
    setState(() => _errorMsg = null);
    try {
      final info = await HardwarePlugin.wifi.getInfo();
      setState(() => _wifi = info);
    } catch (e) { _showError(e); }
  }

  Future<void> _requestPermissions() async {
    setState(() => _errorMsg = null);
    try {
      final ok = await HardwarePlugin.requestPermissions();
      setState(() => _errorMsg = ok ? '✅ Permissions granted' : '⚠️ Some permissions denied');
    } catch (e) { _showError(e); }
  }

  // ── Build ─────────────────────────────────────────────

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Scaffold(
      backgroundColor: const Color(0xFF0F0F1A),
      appBar: AppBar(
        backgroundColor: const Color(0xFF1A1A2E),
        title: const Text('⚡ Hardware SDK', style: TextStyle(
          color: Colors.white, fontWeight: FontWeight.bold,
        )),
        actions: [
          IconButton(
            icon: const Icon(Icons.security, color: Color(0xFF6C63FF)),
            tooltip: 'Request Permissions',
            onPressed: _requestPermissions,
          ),
        ],
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          if (_errorMsg != null) _ErrorBanner(_errorMsg!),

          // ── Bluetooth ─────────────────────────────────
          _SectionCard(
            icon: Icons.bluetooth,
            iconColor: const Color(0xFF6C63FF),
            title: 'Bluetooth LE',
            active: _bleScanning,
            onToggle: _toggleBle,
            statusText: _bleScanning
                ? 'Scanning… ${_devices.length} device(s)'
                : '${_devices.length} device(s) found',
            child: _devices.isEmpty
                ? const _EmptyHint('Start scan to discover BLE devices')
                : Column(
                    children: _devices.take(5).map((d) => _DeviceTile(
                      name: d.name,
                      subtitle: '${d.id}  •  ${d.rssi} dBm',
                    )).toList(),
                  ),
          ),

          // ── GPS ───────────────────────────────────────
          _SectionCard(
            icon: Icons.gps_fixed,
            iconColor: const Color(0xFF43B89C),
            title: 'GPS Location',
            active: _gpsRunning,
            onToggle: _toggleGps,
            statusText: _gpsRunning ? 'Tracking…' : 'Idle',
            child: _lastLocation == null
                ? const _EmptyHint('Start GPS to see live coordinates')
                : _DataGrid([
                    ('Lat', _lastLocation!.latitude.toStringAsFixed(6)),
                    ('Lng', _lastLocation!.longitude.toStringAsFixed(6)),
                    ('Alt', '${_lastLocation!.altitude.toStringAsFixed(1)} m'),
                    ('Acc', '±${_lastLocation!.accuracy.toStringAsFixed(1)} m'),
                    ('Spd', '${(_lastLocation!.speed * 3.6).toStringAsFixed(1)} km/h'),
                  ]),
          ),

          // ── Sensors ───────────────────────────────────
          _SectionCard(
            icon: Icons.sensors,
            iconColor: const Color(0xFFFF6B6B),
            title: 'Accelerometer',
            active: _sensorsRunning,
            onToggle: _toggleSensors,
            statusText: _sensorsRunning ? '60 Hz' : 'Idle',
            child: _lastSample == null
                ? const _EmptyHint('Start sensors to see live X/Y/Z values')
                : _DataGrid([
                    ('X', _lastSample!.x.toStringAsFixed(3)),
                    ('Y', _lastSample!.y.toStringAsFixed(3)),
                    ('Z', _lastSample!.z.toStringAsFixed(3)),
                  ]),
          ),

          // ── Camera ────────────────────────────────────
          _SectionCard(
            icon: Icons.videocam,
            iconColor: const Color(0xFFFFD93D),
            title: 'Camera Frame Stream',
            active: _cameraRunning,
            onToggle: _toggleCamera,
            statusText: _cameraRunning
                ? '$_frameCount frames  •  $_frameBytes B/frame'
                : 'Idle',
            child: _cameraRunning
                ? _DataGrid([
                    ('Frames', '$_frameCount'),
                    ('Payload', '${(_frameBytes / 1024).toStringAsFixed(1)} KB'),
                  ])
                : const _EmptyHint('Start camera to receive binary frames'),
          ),

          // ── WiFi ──────────────────────────────────────
          _SectionCard(
            icon: Icons.wifi,
            iconColor: const Color(0xFF4ECDC4),
            title: 'WiFi Info',
            active: false,
            onToggle: _loadWifi,
            toggleLabel: 'REFRESH',
            statusText: _wifi?.ssid ?? 'Tap REFRESH',
            child: _wifi == null
                ? const _EmptyHint('Tap REFRESH to load network info')
                : _DataGrid([
                    ('SSID',   _wifi!.ssid),
                    ('BSSID',  _wifi!.bssid),
                    ('Signal', '${_wifi!.signalStrength} dBm'),
                    ('IP',     _wifi!.ipAddress),
                  ]),
          ),

          const SizedBox(height: 24),
        ],
      ),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// REUSABLE WIDGETS
// ─────────────────────────────────────────────────────────────────────────────

class _SectionCard extends StatelessWidget {
  final IconData icon;
  final Color iconColor;
  final String title;
  final bool active;
  final VoidCallback onToggle;
  final String statusText;
  final Widget child;
  final String toggleLabel;

  const _SectionCard({
    required this.icon,
    required this.iconColor,
    required this.title,
    required this.active,
    required this.onToggle,
    required this.statusText,
    required this.child,
    this.toggleLabel = '',
  });

  @override
  Widget build(BuildContext context) {
    final label = toggleLabel.isNotEmpty
        ? toggleLabel
        : active ? 'STOP' : 'START';
    return Container(
      margin: const EdgeInsets.only(bottom: 16),
      decoration: BoxDecoration(
        color: const Color(0xFF1A1A2E),
        borderRadius: BorderRadius.circular(16),
        border: Border.all(
          color: active ? iconColor.withAlpha(120) : Colors.white12,
          width: 1.5,
        ),
      ),
      child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 16, 12, 8),
          child: Row(children: [
            Icon(icon, color: iconColor, size: 22),
            const SizedBox(width: 10),
            Expanded(child: Text(title, style: const TextStyle(
              color: Colors.white,
              fontSize: 16,
              fontWeight: FontWeight.w600,
            ))),
            ElevatedButton(
              onPressed: onToggle,
              style: ElevatedButton.styleFrom(
                backgroundColor: active ? Colors.red.shade800 : iconColor,
                foregroundColor: Colors.white,
                padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
                textStyle: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),
                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
              ),
              child: Text(label),
            ),
          ]),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 0, 16, 4),
          child: Text(statusText, style: TextStyle(
            color: active ? iconColor : Colors.white38,
            fontSize: 12,
          )),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 4, 16, 16),
          child: child,
        ),
      ]),
    );
  }
}

class _DataGrid extends StatelessWidget {
  final List<(String, String)> rows;
  const _DataGrid(this.rows);

  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 12,
      runSpacing: 8,
      children: rows.map((r) => Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(r.$1, style: const TextStyle(color: Colors.white38, fontSize: 10)),
          Text(r.$2, style: const TextStyle(
            color: Colors.cyanAccent,
            fontSize: 13,
            fontFamily: 'monospace',
          )),
        ],
      )).toList(),
    );
  }
}

class _DeviceTile extends StatelessWidget {
  final String name;
  final String subtitle;
  const _DeviceTile({required this.name, required this.subtitle});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(children: [
        const Icon(Icons.bluetooth_connected, size: 14, color: Color(0xFF6C63FF)),
        const SizedBox(width: 8),
        Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Text(name, style: const TextStyle(color: Colors.white, fontSize: 13)),
          Text(subtitle, style: const TextStyle(color: Colors.white38, fontSize: 11, fontFamily: 'monospace')),
        ])),
      ]),
    );
  }
}

class _EmptyHint extends StatelessWidget {
  final String text;
  const _EmptyHint(this.text);

  @override
  Widget build(BuildContext context) {
    return Text(text, style: const TextStyle(color: Colors.white24, fontSize: 12));
  }
}

class _ErrorBanner extends StatelessWidget {
  final String message;
  const _ErrorBanner(this.message);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.red.shade900.withAlpha(180),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: Colors.red.shade700),
      ),
      child: Text(message, style: const TextStyle(color: Colors.white, fontSize: 12)),
    );
  }
}
1
likes
150
points
215
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A high-performance Flutter SDK providing native-level hardware access (Camera, Bluetooth, GPS) with responsive UI system and zero-lag architecture.

Repository (GitHub)

Topics

#camera #bluetooth #gps #flutter-plugin #native-ui

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on nexora_sdk

Packages that implement nexora_sdk