super_beacon 0.0.1+1 copy "super_beacon: ^0.0.1+1" to clipboard
super_beacon: ^0.0.1+1 copied to clipboard

Configurable iBeacon monitoring with native events, diagnostics, notifications, and raw manufacturer data.

example/lib/main.dart

import 'dart:async';

import 'package:super_beacon/super_beacon.dart';
import 'package:super_beacon_inspector/super_beacon_inspector.dart';
import 'package:flutter/material.dart';

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

final class ExampleStrings {
  const ExampleStrings();

  String get appTitle => 'Super Beacon Example';
  String get uuidLabel => 'Beacon UUID';
  String get identifierLabel => 'Region identifier';
  String get cooldownLabel => 'Enter cooldown (seconds)';
  String get notificationsLabel => 'Local enter notification';
  String get bluetoothScanLabel => 'iOS manufacturer data scan';
  String get configure => 'Configure';
  String get requestPermissions => 'Request permissions';
  String get start => 'Start monitoring';
  String get stop => 'Stop monitoring';
  String get ready => 'Enter a region configuration.';
  String get configured => 'Configuration saved.';
  String get permissionsRequested => 'Permission request completed.';
  String get monitoringStarted => 'Monitoring started.';
  String get monitoringFailed => 'Monitoring could not start.';
  String get monitoringStopped => 'Monitoring stopped.';
  String get invalidConfiguration => 'Enter a valid UUID and identifier.';
}

final class ExampleController extends ChangeNotifier {
  ExampleController({
    BeaconClient? client,
    BeaconInspectorController? inspectorController,
  }) : _client = client ?? BeaconClient.instance,
       inspectorController = inspectorController ?? BeaconInspectorController();

  final BeaconClient _client;
  final BeaconInspectorController inspectorController;
  final TextEditingController uuidController = TextEditingController();
  final TextEditingController identifierController = TextEditingController();
  final TextEditingController cooldownController = TextEditingController(
    text: '10',
  );
  bool notificationsEnabled = false;
  bool iosBluetoothScanningEnabled = false;
  String status = const ExampleStrings().ready;
  bool busy = false;

  Future<void> handleConfigureClick() async {
    await _run(
      action: () async {
        try {
          final region = BeaconRegion(
            uuid: uuidController.text.trim(),
            identifier: identifierController.text.trim(),
          );
          await _client.configure(
            configuration: BeaconConfiguration(
              regions: <BeaconRegion>[region],
              eventCooldown: Duration(
                seconds: int.tryParse(cooldownController.text.trim()) ?? 10,
              ),
              notifications: BeaconNotificationConfiguration(
                enabled: notificationsEnabled,
                titleTemplate: 'Beacon region entered',
                bodyTemplate: '{regionIdentifier}',
              ),
              iosBluetoothScanningEnabled: iosBluetoothScanningEnabled,
            ),
          );
          status = const ExampleStrings().configured;
        } on ArgumentError {
          status = const ExampleStrings().invalidConfiguration;
        }
      },
    );
  }

  void setNotificationsEnabled({required bool value}) {
    notificationsEnabled = value;
    notifyListeners();
  }

  void setIosBluetoothScanningEnabled({required bool value}) {
    iosBluetoothScanningEnabled = value;
    notifyListeners();
  }

  Future<void> handlePermissionsClick() async {
    await _run(
      action: () async {
        await _client.requestPermissions();
        status = const ExampleStrings().permissionsRequested;
      },
    );
  }

  Future<void> handleStartClick() async {
    await _run(
      action: () async {
        final started = await _client.startMonitoring();
        status = started
            ? const ExampleStrings().monitoringStarted
            : const ExampleStrings().monitoringFailed;
        await inspectorController.refresh();
      },
    );
  }

  Future<void> handleStopClick() async {
    await _run(
      action: () async {
        await _client.stopMonitoring();
        status = const ExampleStrings().monitoringStopped;
        await inspectorController.refresh();
      },
    );
  }

  Future<void> _run({required Future<void> Function() action}) async {
    if (busy) {
      return;
    }
    busy = true;
    notifyListeners();
    try {
      await action();
    } finally {
      busy = false;
      notifyListeners();
    }
  }

  @override
  void dispose() {
    uuidController.dispose();
    identifierController.dispose();
    cooldownController.dispose();
    inspectorController.dispose();
    super.dispose();
  }
}

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

  @override
  Widget build(BuildContext context) {
    const strings = ExampleStrings();
    Widget resultWidget = const SuperBeaconExamplePage();
    resultWidget = MaterialApp(
      debugShowCheckedModeBanner: false,
      title: strings.appTitle,
      theme: ThemeData(useMaterial3: true),
      localizationsDelegates:
          BeaconInspectorLocalizations.localizationsDelegates,
      supportedLocales: BeaconInspectorLocalizations.supportedLocales,
      home: resultWidget,
    );
    return resultWidget;
  }
}

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

  @override
  State<SuperBeaconExamplePage> createState() => _SuperBeaconExamplePageState();
}

class _SuperBeaconExamplePageState extends State<SuperBeaconExamplePage> {
  final ExampleStrings strings = const ExampleStrings();
  late final ExampleController controller;

  @override
  void initState() {
    super.initState();
    controller = ExampleController();
    controller.addListener(_handleChanged);
  }

  @override
  void dispose() {
    controller.removeListener(_handleChanged);
    controller.dispose();
    super.dispose();
  }

  void _handleChanged() {
    if (mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget resultWidget = _buildBody();
    resultWidget = Scaffold(appBar: _buildAppBar(), body: resultWidget);
    return resultWidget;
  }

  PreferredSizeWidget _buildAppBar() {
    Widget title = Text(strings.appTitle);
    final PreferredSizeWidget resultWidget = AppBar(title: title);
    return resultWidget;
  }

  Widget _buildBody() {
    Widget resultWidget = Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        _buildConfigurationPanel(),
        Expanded(child: _buildInspector()),
      ],
    );
    resultWidget = SafeArea(child: resultWidget);
    return resultWidget;
  }

  Widget _buildConfigurationPanel() {
    Widget resultWidget = Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        _buildUuidField(),
        const SizedBox(height: 8),
        _buildIdentifierField(),
        const SizedBox(height: 8),
        _buildCooldownField(),
        _buildConfigurationSwitches(),
        const SizedBox(height: 12),
        _buildActions(),
        const SizedBox(height: 8),
        _buildStatus(),
      ],
    );
    resultWidget = Padding(
      padding: const EdgeInsets.all(16),
      child: resultWidget,
    );
    return resultWidget;
  }

  Widget _buildCooldownField() {
    return TextField(
      controller: controller.cooldownController,
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
        border: const OutlineInputBorder(),
        labelText: strings.cooldownLabel,
      ),
    );
  }

  Widget _buildConfigurationSwitches() {
    return Column(
      children: <Widget>[
        SwitchListTile(
          contentPadding: EdgeInsets.zero,
          title: Text(strings.notificationsLabel),
          value: controller.notificationsEnabled,
          onChanged: (value) {
            controller.setNotificationsEnabled(value: value);
          },
        ),
        SwitchListTile(
          contentPadding: EdgeInsets.zero,
          title: Text(strings.bluetoothScanLabel),
          value: controller.iosBluetoothScanningEnabled,
          onChanged: (value) {
            controller.setIosBluetoothScanningEnabled(value: value);
          },
        ),
      ],
    );
  }

  Widget _buildUuidField() {
    Widget resultWidget = TextField(
      controller: controller.uuidController,
      decoration: InputDecoration(
        border: const OutlineInputBorder(),
        labelText: strings.uuidLabel,
      ),
    );
    return resultWidget;
  }

  Widget _buildIdentifierField() {
    Widget resultWidget = TextField(
      controller: controller.identifierController,
      decoration: InputDecoration(
        border: const OutlineInputBorder(),
        labelText: strings.identifierLabel,
      ),
    );
    return resultWidget;
  }

  Widget _buildActions() {
    Widget resultWidget = Wrap(
      spacing: 8,
      runSpacing: 8,
      children: <Widget>[
        _buildActionButton(
          label: strings.configure,
          icon: Icons.settings,
          action: controller.handleConfigureClick,
        ),
        _buildActionButton(
          label: strings.requestPermissions,
          icon: Icons.security,
          action: controller.handlePermissionsClick,
        ),
        _buildActionButton(
          label: strings.start,
          icon: Icons.play_arrow,
          action: controller.handleStartClick,
        ),
        _buildActionButton(
          label: strings.stop,
          icon: Icons.stop,
          action: controller.handleStopClick,
        ),
      ],
    );
    return resultWidget;
  }

  Widget _buildActionButton({
    required String label,
    required IconData icon,
    required Future<void> Function() action,
  }) {
    final iconWidget = Icon(icon);
    final labelWidget = Text(label);
    Widget resultWidget = FilledButton.icon(
      onPressed: controller.busy ? null : action,
      icon: iconWidget,
      label: labelWidget,
    );
    return resultWidget;
  }

  Widget _buildStatus() {
    Widget resultWidget = Text(controller.status);
    return resultWidget;
  }

  Widget _buildInspector() {
    Widget resultWidget = BeaconInspectorView(
      controller: controller.inspectorController,
    );
    return resultWidget;
  }
}
0
likes
150
points
34
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Configurable iBeacon monitoring with native events, diagnostics, notifications, and raw manufacturer data.

Repository (GitHub)
View/report issues

Topics

#beacon #bluetooth #ibeacon #location #diagnostics

License

Apache-2.0 (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on super_beacon

Packages that implement super_beacon