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

Flutter plugin for the Beekon location SDK (Android + iOS).

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Beekon Flutter Example',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.amber),
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final List<Position> _liveFeed = <Position>[];
  String? _error;

  @override
  void initState() {
    super.initState();
    _bootstrap();
    Beekon.instance.positions.listen((Position p) {
      setState(() {
        _liveFeed.insert(0, p);
        if (_liveFeed.length > 100) _liveFeed.removeLast();
      });
    });
  }

  Future<void> _bootstrap() async {
    try {
      await Beekon.instance.initialize();
      await Beekon.instance.configure(
        const BeekonConfig(
          preset: BeekonPreset.balanced,
          androidNotification: AndroidNotification(
            channelId: 'beekon-tracking',
            channelName: 'Tracking',
            notificationId: 7411,
            title: 'Beekon',
            text: 'Tracking your location',
            // mipmap/ic_launcher always exists in a flutter create scaffold.
            smallIcon: 'ic_launcher',
          ),
        ),
      );
    } catch (e) {
      setState(() => _error = e.toString());
    }
  }

  Future<void> _toggle(BeekonState current) async {
    try {
      if (current is Tracking || current is Starting) {
        await Beekon.instance.stop();
      } else {
        await Beekon.instance.start();
      }
    } catch (e) {
      setState(() => _error = e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Beekon Flutter Example'),
        actions: <Widget>[
          IconButton(
            tooltip: 'History',
            icon: const Icon(Icons.history),
            onPressed: () => Navigator.of(context).push(
              MaterialPageRoute<void>(
                builder: (BuildContext _) => const HistoryPage(),
              ),
            ),
          ),
        ],
      ),
      body: StreamBuilder<BeekonState>(
        stream: Beekon.instance.state,
        initialData: const Idle(),
        builder: (BuildContext context, AsyncSnapshot<BeekonState> snap) {
          final BeekonState state = snap.data ?? const Idle();
          return Column(
            children: <Widget>[
              _StatusCard(state: state, error: _error),
              Padding(
                padding: const EdgeInsets.all(16),
                child: FilledButton.icon(
                  icon: Icon(_isActive(state) ? Icons.stop : Icons.play_arrow),
                  label: Text(_isActive(state) ? 'Stop' : 'Start'),
                  onPressed: () => _toggle(state),
                ),
              ),
              const Divider(),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    const Text('Live positions'),
                    Text('${_liveFeed.length} buffered',
                        style: Theme.of(context).textTheme.bodySmall),
                  ],
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: _liveFeed.length,
                  itemBuilder: (BuildContext context, int i) {
                    final Position p = _liveFeed[i];
                    return _PositionTile(p: p);
                  },
                ),
              ),
            ],
          );
        },
      ),
    );
  }

  bool _isActive(BeekonState s) => s is Tracking || s is Starting;
}

class _StatusCard extends StatelessWidget {
  const _StatusCard({required this.state, required this.error});
  final BeekonState state;
  final String? error;

  @override
  Widget build(BuildContext context) {
    final ThemeData t = Theme.of(context);
    final String label = switch (state) {
      Idle() => 'Idle',
      Starting() => 'Starting…',
      Tracking() => 'Tracking',
      Paused(reason: final PauseReason r) => 'Paused (${r.name})',
      Stopped() => 'Stopped',
    };
    return Card(
      margin: const EdgeInsets.all(16),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('State', style: t.textTheme.bodySmall),
            const SizedBox(height: 4),
            Text(label, style: t.textTheme.headlineSmall),
            if (error != null) ...<Widget>[
              const SizedBox(height: 8),
              Text(error!,
                  style: t.textTheme.bodySmall?.copyWith(
                      color: t.colorScheme.error)),
            ],
          ],
        ),
      ),
    );
  }
}

class _PositionTile extends StatelessWidget {
  const _PositionTile({required this.p});
  final Position p;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      dense: true,
      leading: const Icon(Icons.place_outlined, size: 20),
      title: Text('${p.lat.toStringAsFixed(5)}, ${p.lng.toStringAsFixed(5)}'),
      subtitle: Text(
        '±${p.accuracy.toStringAsFixed(1)} m   •   '
        '${p.speed.toStringAsFixed(1)} m/s   •   '
        '${p.timestamp.toLocal()}',
      ),
    );
  }
}

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

class _HistoryPageState extends State<HistoryPage> {
  late DateTime _from;
  late DateTime _to;
  Future<List<Position>>? _future;

  @override
  void initState() {
    super.initState();
    _to = DateTime.now();
    _from = _to.subtract(const Duration(hours: 24));
  }

  Future<void> _pickRange() async {
    final DateTimeRange? range = await showDateRangePicker(
      context: context,
      firstDate: DateTime(2025),
      lastDate: DateTime.now(),
      initialDateRange: DateTimeRange(start: _from, end: _to),
    );
    if (range != null) {
      setState(() {
        _from = range.start;
        _to = range.end;
        _future = Beekon.instance.history(from: _from, to: _to);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('History'),
        actions: <Widget>[
          IconButton(
            tooltip: 'Pick date range',
            icon: const Icon(Icons.date_range),
            onPressed: _pickRange,
          ),
        ],
      ),
      body: FutureBuilder<List<Position>>(
        future: _future ??= Beekon.instance.history(from: _from, to: _to),
        builder:
            (BuildContext context, AsyncSnapshot<List<Position>> snap) {
          if (snap.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snap.hasError) {
            return Center(child: Text('Error: ${snap.error}'));
          }
          final List<Position> rows = snap.data ?? <Position>[];
          if (rows.isEmpty) {
            return const Center(child: Text('No history in this range.'));
          }
          return ListView.builder(
            itemCount: rows.length,
            itemBuilder: (BuildContext context, int i) =>
                _PositionTile(p: rows[i]),
          );
        },
      ),
    );
  }
}
0
likes
150
points
129
downloads

Documentation

API reference

Publisher

verified publisherwayq.in

Weekly Downloads

Flutter plugin for the Beekon location SDK (Android + iOS).

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, meta, plugin_platform_interface

More

Packages that depend on beekon_flutter

Packages that implement beekon_flutter