flutter_ttc_ble 0.0.2
flutter_ttc_ble: ^0.0.2 copied to clipboard
Android BLE(Bluetooth Low Energy) Flutter plugin.
example/lib/main.dart
import 'dart:async';
import 'dart:typed_data';
import 'package:convert/convert.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ttc_ble/flutter_ttc_ble.dart';
import 'communication.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
List<BLEDevice> _dataList = <BLEDevice>[];
@override
void initState() {
super.initState();
print('main -> initState()');
WidgetsBinding.instance.addObserver(this);
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
//TODO BLE 插件初始化
FlutterTtcBle.init();
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
}
@override
void didChangeDependencies() {
print('main -> didChangeDependencies()');
super.didChangeDependencies();
}
@override
void didUpdateWidget(MyApp oldWidget) {
//当树rebuid的时候会调用该方法
print('main -> didUpdateWidget()');
super.didUpdateWidget(oldWidget);
}
@override
void deactivate() {
//当State对象从树中被移除时,会调用此回调。
print('main -> deactivate()');
super.deactivate();
}
@override
void dispose() {
//当State对象从树中被永久移除时调用;通常在此回调中释放资源。
print('main -> dispose()');
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
//Flutter生命周期:https://blog.csdn.net/brycegao321/article/details/86583223
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('main -> didChangeAppLifecycleState() - state=$state');
super.didChangeAppLifecycleState(state);
}
@override
Widget build(BuildContext context) {
//print('main -> build()');
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter BLE Demo V1.0'),
),
body: RefreshIndicator(
onRefresh: _refresh,
child: ListView.builder(
itemCount: _dataList.length,
itemBuilder: (context, index) {
return _buildRow(_dataList[index]);
},
),
),
),
);
}
///下拉刷新(扫描设备)
Future<Null> _refresh() async {
setState(() {
_dataList.clear();
});
FlutterTtcBle.startLeScan((device) {
setState(() {
//刷新UI要在setState()方法内进行
//为了防止列表中设备重复,这里判断一下
if (!_dataList.contains(device)) _dataList.add(device);
});
});
await Future.delayed(Duration(seconds: 5), () {
print('refresh() - delayed 5s');
setState(() {
//
});
});
}
///加载列表项
Widget _buildRow(BLEDevice device) {
// 这里使用 Builder 避免异常:Navigator operation requested with a context that does not include a Navigator.
// 参考 https://blog.csdn.net/nimeghbia/article/details/84388725
return Builder(
builder: (context) => new ListTile(
title: new Text(
device.name != null ? device.name : "Unknown Device",
),
subtitle: new Text(
'${device.deviceId}'
'\nAdvertisData=${_advertisDataToString(device.advertisData)}'
'\nServiceUUIDs=${device.advertisServiceUUIDs}'
'\nServiceData=${_serviceDataToString(device.serviceData)}',
),
onTap: () {
_toCommPage(context, device);
},
),
);
}
String _advertisDataToString(Uint8List advertisData) {
return advertisData == null ? "" : hex.encode(advertisData);
}
String _serviceDataToString(Map<String, Uint8List> serviceData) {
StringBuffer sb = StringBuffer('{');
int i = 0;
serviceData.forEach((uuid, data) => (String uuid, Uint8List data) {
sb.write("$uuid: ${hex.encode(data)}");
if (i < serviceData.length - 1) {
sb.write(', ');
}
i++;
});
sb.write('}');
return sb.toString();
}
///跳转到数据交互页面
void _toCommPage(BuildContext context, BLEDevice device) async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (BuildContext context) => CommPage(device)),
);
print('从数据交互页面返回 $result');
///这是在页面底部显示一个弹出提示
//Scaffold.of(context).showSnackBar(SnackBar(content: Text(result)));
//TODO 监听平台消息
}
}