I am a student studying flutter. While implementing BLE communication in Flutter, information about ibeacon is not received. I am using flutter_blue_plus, but I would appreciate it if you could provide a better library or example code that can receive the value of ibeacon.
I tried using flutter_blue_plus, beacons_plugin, etc., but it was difficult to utilize them due to insufficient examples. I would like to receive a statefulwidget code that can detect ibeacon.
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
FlutterBluePlus flutterBlue = FlutterBluePlus.instance;
List<ScanResult> scanResultList = [];
bool _isScanning = false;
@override
initState() {
super.initState();
// 블루투스 초기화
initBle();
}
void initBle() {
// BLE 스캔 상태 얻기 위한 리스너
flutterBlue.isScanning.listen((isScanning) {
_isScanning = isScanning;
setState(() {});
});
}
bool _isIBeacon(List<String> data) {
print(data);
return data.length == 25 &&
data[0] == '0x4c' &&
data[1] == '0x00' &&
data[2] == '0x02' &&
data[3] == '0x15';
}
scan() async {
if (!_isScanning) {
// 스캔 중이 아니라면
// 기존에 스캔된 리스트 삭제
scanResultList.clear();
// 스캔 시작, 제한 시간 4초
flutterBlue.startScan(
timeout: Duration(seconds: 10));
print('scanResults : ${flutterBlue.scanResults}');
// 스캔 결과 리스너
flutterBlue.scanResults.listen((results) {
print('result : $results');
for (ScanResult result in results) {
// Get all the data from advertisement
Map<int, List<int>> adData = result.advertisementData.manufacturerData;
for (int id in adData.keys) {
print('Manufacturer ID: $id');
List<int> data = adData[id]!;
List<String> hex = [];
String bytesToHex(List<int> bytes) {
return bytes.map((byte) {
// 각 바이트를 2자리 16진수로 포맷팅
hex.add(byte.toRadixString(16).padLeft(2, '0'));
return byte.toRadixString(16).padLeft(2, '0');
}).join(' '); // 각 16진수를 공백으로 구분
}
String hexString = bytesToHex(data);
print('hexString : ${hex}');
if (_isIBeacon(hex)) {
print('This is an iBeacon');
// Now you can parse the array 'data' as an iBeacon.
}
}
}
// List<ScanResult> 형태의 results 값을 scanResultList에 복사
scanResultList = results;
List data = scanResultList.toList();
for (ScanResult r in results) {
final serviceData = r.advertisementData.serviceData;
final serviceUuids = r.advertisementData.serviceUuids;
print('${r.device.id}: $serviceUuids $serviceData');
}
// UI 갱신
setState(() {});
});
} else {
// 스캔 중이라면 스캔 정지
flutterBlue.stopScan();
}
}
Widget deviceSignal(ScanResult r) {
return Text(r.rssi.toString());
}
/* 장치의 MAC 주소 위젯 */
Widget deviceMacAddress(ScanResult r) {
return Text(r.device.id.id);
}
/* 장치의 명 위젯 */
Widget deviceName(ScanResult r) {
String name = '';
if (r.device.name.isNotEmpty) {
// device.name에 값이 있다면
name = r.device.name;
} else if (r.advertisementData.localName.isNotEmpty) {
// advertisementData.localName에 값이 있다면
name = r.advertisementData.localName;
} else {
// 둘다 없다면 이름 알 수 없음...
name = 'N/A';
}
return Text(name);
}
Widget leading(ScanResult r) {
return CircleAvatar(
child: Icon(
Icons.bluetooth,
color: Colors.white,
),
backgroundColor: Colors.cyan,
);
}
/* 장치 아이템을 탭 했을때 호출 되는 함수 */
void onTap(ScanResult r) {
// 단순히 이름만 출력
print('${r.device.name}');
}
/* 장치 아이템 위젯 */
Widget listItem(ScanResult r) {
return ListTile(
onTap: () => onTap(r),
leading: leading(r),
title: deviceName(r),
subtitle: deviceMacAddress(r),
trailing: deviceSignal(r),
);
}
/* UI */
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true
),
home: Scaffold(
appBar: AppBar(
title: Text('Ble'),
),
body: Center(
/* 장치 리스트 출력 */
child: ListView.separated(
itemCount: scanResultList.length,
itemBuilder: (context, index) {
return listItem(scanResultList[index]);
},
separatorBuilder: (BuildContext context, int index) {
return Divider();
},
),
),
/* 장치 검색 or 검색 중지 */
floatingActionButton: FloatingActionButton(
onPressed: scan,
// 스캔 중이라면 stop 아이콘을, 정지상태라면 search 아이콘으로 표시
child: Icon(_isScanning ? Icons.stop : Icons.search),
),
),
);
}
}