beacon_util 0.0.3
beacon_util: ^0.0.3 copied to clipboard
This is a Flutter plugin project for iOS that handles Bluetooth beacon scanning and management.
example/lib/main.dart
import 'package:beacon_util/beacon.dart';
import 'package:beacon_util/beacon_message.dart';
import 'package:beacon_util/beacon_plugin.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _BeaconStateText extends StatefulWidget {
const _BeaconStateText();
@override
State<_BeaconStateText> createState() => _BeaconStateTextState();
}
class _BeaconStateTextState extends State<_BeaconStateText> {
BeaconState beaconState = BeaconState.initial;
@override
void initState() {
BeaconPlugin.beaconStateController.stream.listen((state) {
if (beaconState == state) return; // Avoid unnecessary rebuilds
setState(() {
beaconState = state;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
spacing: 10,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
beaconState.name,
style: const TextStyle(fontSize: 16),
textAlign: TextAlign.center,
),
Visibility(
visible: beaconState == BeaconState.scanning,
child: SizedBox(
width: 10,
height: 10,
child: CircularProgressIndicator(
strokeWidth: 3,
color: Colors.blue,
),
),
),
],
);
}
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
spacing: 20,
children: [
const SizedBox.shrink(),
_buttonsView(),
_beaconStateView(),
_beaconListView(),
],
),
),
),
);
}
Widget _buttonsView() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blue.withAlpha(200),
foregroundColor: Colors.white,
),
onPressed: BeaconPlugin.startScan,
child: const Text('scan'),
),
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.pink.withAlpha(200),
foregroundColor: Colors.white,
),
onPressed: BeaconPlugin.stopScan,
child: const Text('stop'),
),
],
);
}
Widget _beaconStateView() {
return Padding(
padding: const EdgeInsets.only(left: 16),
child: Row(
spacing: 10,
children: [
Text('Beacon State:', style: TextStyle(fontSize: 16)),
_BeaconStateText(),
],
),
);
}
Widget _beaconListView() {
return StreamBuilder<List<Beacon>>(
stream: BeaconPlugin.receiveBeacons(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final beacons = snapshot.data!;
if (beacons.isEmpty) {
return const Text('No beacons found.');
}
return Expanded(
child: ListView.separated(
itemCount: beacons.length,
itemBuilder: (context, index) {
final beacon = beacons[index];
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Name: ${beacon.name}',
style: const TextStyle(fontSize: 16),
),
Text(
'UUID: ${beacon.uuid}',
style: const TextStyle(fontSize: 14),
),
Text(
'Major: ${beacon.major}, Minor: ${beacon.minor}, RSSI: ${beacon.rssi}',
style: const TextStyle(fontSize: 10),
),
],
),
);
},
separatorBuilder: (context, index) => const Divider(),
),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
return SizedBox.shrink();
},
);
}
}