Flutter getX RangeError Invalid value - flutter

so i'm new to getX package i'm trying to convert my actual app into getX.
I'm having an error that's causing my api response to say this in the console :
I/flutter ( 4915): Error 401
I/flutter ( 4915): Response Body getAllUserBikes
I/flutter ( 4915): {"statusCode":401,"error":"Unauthorized","message":"Invalid token."}
My home_page_controller.dart
class HomePageController extends GetxController{
UserController userController = Get.put(UserController());
StorageController storageController = Get.put(StorageController());
List<Bike> bikeList = [];
String query = '';
Rx<UserModel> user = UserModel().obs;
Color black = Colors.black;
Color vert = Color.fromARGB(255, 118, 157, 103);
Color petrole = Color.fromARGB(255, 32, 56, 100);
Color nocolor = Color.fromARGB(255, 155, 155, 155);
Color beige = Color.fromARGB(255, 253, 239, 206);
//Functions
Color textColor(Color backgroundColor) {
if (backgroundColor == petrole || backgroundColor == black) {
return Colors.white;
} else if (backgroundColor == beige) {
return black;
} else {
return Colors.black;
}
}
Color getColorFromString(String stringColor) {
if (stringColor == "pétrole" || stringColor == "petrole") {
return petrole;
} else if (stringColor == "noir") {
return black;
} else if (stringColor == "vert eau") {
return vert;
} else if (stringColor == "beige") {
return beige;
} else {
return nocolor;
}
}
final bicycodeDefault = [0x14, 0x22, 0x01, 0x00];
final bicycode = hex.decode(14.toString());
Future<void> initBikeList() async {
List<Bike> list = await APIBike().getAllNotFinishedBikes(jwt: user.value.jwt);
developer.log('Ma liste = ${list.toString()}');
List<Bike> maList = list;
for (int i = 0; i == list.length; i++) {
//RangeError (RangeError (index): Invalid value: Valid value range is empty: 0)
if (list[i].status == "assembling") {
maList.first = list[i];
}
bikeList = maList;
update();
}
}
init() async {
await initBikeList();
}
void onInit() {
super.onInit();
init();
//APIBle().generateBicycode();
}
void getStorage() {
user.value = UserModel.storageFromJson(storageController.getData(key: "user"));
// print(storageController.getData(key: "user"));
}
Future initStorage() async {
getStorage();
}
}
my API (only the part where it fetch all the data into a list)
Future<List<Bike>> getAllNotFinishedBikes({
required String jwt,
}) async {
var client = new http.Client();
var response = await client
.get(Uri.parse("$serverAddress/bikes?status=ne_finish"), headers: {
"Content-Type": 'application/json',
'Authorization': 'Bearer $jwt'
});
if (response.statusCode == 200) {
print("SUCCESS getAllNotFinishedBikes");
print(response);
developer.log(response.body);
print("LENGHT");
developer.log(response.body.length.toString());
var body = response.body.toString();
final List<dynamic> parsed = jsonDecode(body) as List<dynamic>;
/*print("RAW BODY");*/
print("PARSED");
print(parsed);
try {
List<Bike> listOfBikes = createBikesList(parsed);
print(parsed.length.toString() + " bike(s) scanned successfully");
return listOfBikes;
} catch (e) {
print(
"Error while trying to parse parsed json in getAllNotFinishedBikes");
print(e);
return [];
}
} else {
print("Error " + response.statusCode.toString());
print("Response Body getAllUserBikes");
print(response.body);
return []; //we return an empty list
}
}
I feel like the problem is from how i did my controller, maybe a way to make my list observable with getX ?
I can provide more codes if needed.
Thanks u all, help is appreciated !

change this line :
for (int i = 0; i == list.length; i++) {
to
for (int i = 0; i < list.length; i++) {

Related

Unhandled Exception: Bad state: Tried to use PaginationNotifier after `dispose` was called

I have a StateNotifierProvider that calls an async function which loads some images from the internal storage and adds them to the AsyncValue data:
//Provider declaration
final paginationImagesProvider = StateNotifierProvider.autoDispose<PaginationNotifier, AsyncValue<List<Uint8List?>>>((ref) {
return PaginationNotifier(folderId: ref.watch(localStorageSelectedFolderProvider), itemsPerBatch: 100, ref: ref);
});
//Actual class with AsyncValue as State
class PaginationNotifier extends StateNotifier<AsyncValue<List<Uint8List?>>> {
final int itemsPerBatch;
final String folderId;
final Ref ref;
int _numberOfItemsInFolder = 0;
bool _alreadyFetching = false;
bool _hasMoreItems = true;
PaginationNotifier({required this.itemsPerBatch, required this.folderId, required this.ref}) : super(const AsyncValue.loading()) {
log("PaginationNotifier created with folderId: $folderId, itemsPerBatch: $itemsPerBatch");
init();
}
final List<Uint8List?> _items = [];
void init() {
if (_items.isEmpty) {
log("fetchingFirstBatch");
_fetchFirstBatch();
}
}
Future<List<Uint8List?>> _fetchNextItems() async {
List<AssetEntity> images = (await (await PhotoManager.getAssetPathList())
.firstWhere((element) => element.id == folderId)
.getAssetListRange(start: _items.length, end: _items.length + itemsPerBatch));
List<Uint8List?> newItems = [];
for (AssetEntity image in images) {
newItems.add(await image.thumbnailData);
}
return newItems;
}
void _updateData(List<Uint8List?> result) {
if (result.isEmpty) {
state = AsyncValue.data(_items);
} else {
state = AsyncValue.data(_items..addAll(result));
}
_hasMoreItems = _numberOfItemsInFolder > _items.length;
}
Future<void> _fetchFirstBatch() async {
try {
_numberOfItemsInFolder = await (await PhotoManager.getAssetPathList()).firstWhere((element) => element.id == folderId).assetCountAsync;
state = const AsyncValue.loading();
final List<Uint8List?> result = await _fetchNextItems();
_updateData(result);
} catch (e, stk) {
state = AsyncValue.error(e, stk);
}
}
Future<void> fetchNextBatch() async {
if (_alreadyFetching || !_hasMoreItems) return;
_alreadyFetching = true;
log("data updated");
state = AsyncValue.data(_items);
try {
final result = await _fetchNextItems();
_updateData(result);
} catch (e, stk) {
state = AsyncValue.error(e, stk);
log("error catched");
}
_alreadyFetching = false;
}
}
Then I use a scroll controller attached to a CustomScrollView in order to call fetchNextBatch() when the scroll position changes:
#override
void initState() {
if (!controller.hasListeners && !controller.hasClients) {
log("listener added");
controller.addListener(() {
double maxScroll = controller.position.maxScrollExtent;
double position = controller.position.pixels;
if ((position > maxScroll * 0.2 || position == 0) && ref.read(paginationImagesProvider.notifier).mounted) {
ref.read(paginationImagesProvider.notifier).fetchNextBatch();
}
});
}
super.initState();
}
The problem is that when the StateNotifierProvider is fetching more data in the async function fetchNextBatch() and I go back on the navigator (like navigator.pop()), Flutter gives me an error:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Tried to use PaginationNotifier after dispose was called.
Consider checking mounted.
I think that the async function responsible of loading data completes after I've popped the page from the Stack (which triggers a Provider dispose).
I'm probably missing something and I still haven't found a fix for this error, any help is appreciated.

Pull to refresh package in flutter for pagination purpose

Hello Readers I am new in flutter and i want to do pagination, for pagination I am using one package which name is "pull to refersh".
Problems :
I have total 6 post and per page limits are 3.
1)When I reached at the end of list then api will call and set current page variable value is 2 and it will load all data of page 2 as a new list, but i want to merge page 2 data into same list... (Pagination like facebook instagram etc).
2)My another problem is when i pull for refersh, page is refersh perfectly and it will go to the first page but problem is, when i again go at the end of list it shows me no more data(which means page 2 api is not working)
I have one condition like if else:- "hasNextPage" this variable getting from api and the response is 1 or 2, if response is 1 then there further page after current page and if is 0 then there is no page after current page.
I am posting my code and api link also can you please help me.
Method for get data from API
int currentPage = 1;
bool isRefersh = false;
final RefreshController refreshController = RefreshController();
Future<UserPost> getUserPost() async {
var url =
"LINK=$currentPage";
var response = await http.get(Uri.parse(url));
var jsondata = jsonDecode(response.body.toString());
var _apiData = UserPost.fromJson(jsondata);
if (response.statusCode == 200) {
print("******getUserPost API");
print("current page****$currentPage");
print("hasnext page ${_apiData.hasNextPage}");
print(jsondata);
if(isRefersh == true){
setState((){
//currentPage = 1;
isRefersh = false;
});
refreshController.refreshCompleted();
return UserPost.fromJson(jsondata);
}
else{
print("//////////////// has next page");
print(_apiData.hasNextPage.toString());
if(_apiData.hasNextPage == 0){
refreshController.loadNoData();
return UserPost.fromJson(jsondata);
}else{
}
return UserPost.fromJson(jsondata);
}
} else {
return UserPost.fromJson(jsondata);
}
}
Method for pull to Refersh
onRefresh: () async{
await Future.delayed(Duration(milliseconds: 1000));
setState(() {
isRefersh = true;
currentPage = 1;
});
},
Method for Pagination
onLoading: () async {
if(snapshot.data!.hasNextPage == 0){
refreshController.loadNoData();
}else{
setState(() {
currentPage++;
});
await Future.delayed(Duration(milliseconds: 1000));
refreshController.loadComplete();
}
},
I Hope it's help you
try this way :-
final RefreshController refreshController =
RefreshController(initialRefresh: true);
Future<bool> getPassengerData({bool isRefresh = false}) async {
if (isRefresh) {
currentPage = 1;
} else {
if (currentPage >= totalPages) {
refreshController.loadNoData();
return false;
}
}
final Uri uri = Uri.parse(
"api url=$currentPage&size=10");
final response = await http.get(uri);
if (response.statusCode == 200) {
final result = passengersDataFromJson(response.body);
if (isRefresh) {
passengers = result.data;
}else{
passengers.addAll(result.data);
}
currentPage++;
totalPages = result.totalPages;
print(response.body);
setState(() {});
return true;
} else {
return false;
}
}
Method for pull to Refersh
onRefresh: () async {
final result = await getPassengerData(isRefresh: true);
if (result) {
refreshController.refreshCompleted();
} else {
refreshController.refreshFailed();
}
},
Method for onLoading:
onLoading: () async {
final result = await getPassengerData();
if (result) {
refreshController.loadComplete();
} else {
refreshController.loadFailed();
}
},
Try this way.
when you get the response in second page just create new list with previous list.
i.e var newData = [...?dummyData.data, ...?_apiData.data];
than return this same list.
UserPostModel dummyData = UserPostModel();
Future<UserPostModel> getUserPost() async {
var url =
"*****?page=$currentPage";
var response = await http.get(Uri.parse(url));
var jsondata = jsonDecode(response.body.toString());
var _apiData = UserPostModel.fromJson(jsondata);
var newData = [...?dummyData.data, ...?_apiData.data];
//totalPage = _apiData.totalPages as int?;
if (response.statusCode == 200) {
if (isRefersh == true) {
setState(() {
isRefersh = false;
});
refreshController.refreshCompleted();
} else {
if (_apiData.hasNextPage == 0) {
refreshController.loadNoData();
} else {
refreshController.loadComplete();
}
}
dummyData.data = newData;
return dummyData;
} else {
return dummyData;
}
}

rangeError (RangeError (index): Invalid value: Not in inclusive range 0..4: 5)

So basically I'm making an Inventory Management System using flutter desktop.
this is my code,
InventoryPage.dart
// get all posts
Future<void> getData() async {
Response response = await getInventoryMonthly(tanggal);
if (response.error == null) {
setState(() {
_inventoryList = response.data as List;
if(formattedLastDate == DateFormat('yyyy-MM-dd').format(DateTime(date.year, date.month+1, 0))){
print("Benar!");
}else{
for (var i = 0; i < _inventoryList.length; i++) {
addInventory(
_inventoryList[i]['id_kategori'],
_inventoryList[i]['id_gudang'],
_inventoryList[i]['id_brand'],
_inventoryList[i]['nama'],
_inventoryList[i]['parts_no'],
_inventoryList[i]['new_parts'],
_inventoryList[i]['satuan'],
_inventoryList[i]['jumlah_akhir'],
0.0,
0.0,
_inventoryList[i]['jumlah_akhir'],
_inventoryList[i]['harga'],
_inventoryList[i]['image'],
tanggal,
);
}
print(formattedLastDate);
print(DateFormat('yyyy-MM-dd').format(DateTime(date.year, date.month+1, 0)));
// print(formattedLastDate);
print("salah!");
}
_loading = _loading ? !_loading : _loading;
});
} else if (response.error == unauthorized) {
logOut().then((value) => {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => Login()),
(route) => false)
});
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('${response.error}'),
));
}
}
AddInventory Future
// Add barang
Future<Response> addInventory(
int? id_kategori,
int? id_gudang,
int? id_brand,
String? nama,
var parts_no,
var new_parts,
var satuan,
num? jumlah_awal,
num? jumlah_masuk,
num? jumlah_keluar,
num? jumlah_akhir,
num? harga,
var image,
var created_month,
) async {
Response res = Response();
try {
String token = await getToken();
final response = await http.post(Uri.parse(barangURL),
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $token'
},
body: image != null
? {
"id_kategori": id_kategori.toString(),
"id_gudang": id_gudang.toString(),
"id_brand": id_brand.toString(),
"nama": nama,
"parts_no": parts_no,
"new_parts": new_parts,
"satuan": satuan,
"jumlah_awal": jumlah_awal.toString(),
"jumlah_masuk": jumlah_masuk.toString(),
"jumlah_keluar": jumlah_keluar.toString(),
"jumlah_akhir": jumlah_akhir.toString(),
"harga": harga.toString(),
"image": image,
"created_month": created_month,
}
: {
"id_kategori": id_kategori.toString(),
"id_gudang": id_gudang.toString(),
"id_brand": id_brand.toString(),
"nama": nama,
"parts_no": parts_no,
"new_parts": new_parts,
"satuan": satuan,
"jumlah_awal": jumlah_awal.toString(),
"jumlah_masuk": jumlah_masuk.toString(),
"jumlah_keluar": jumlah_keluar.toString(),
"jumlah_akhir": jumlah_akhir.toString(),
"harga": harga.toString(),
"created_month": created_month.toString(),
});
switch (response.statusCode) {
case 200:
print(jsonDecode(response.body));
res.data = jsonDecode(response.body);
break;
case 422:
final errors = jsonDecode(response.body)['errors'];
res.error = errors[errors.keys.elementAt(0)][0];
break;
case 401:
res.error = unauthorized;
break;
default:
res.error = somethingWentWrong;
break;
}
} catch (e) {
res.error = serverError;
}
return res;
}
My goal is to simply make it so that flutter will automatically create Similiar Data and values at the end of the month. This is one of the error that I've got:
rangeError (RangeError (index): Invalid value: Not in inclusive range 0..4: 5)
Please can anyone help me with this?
Thanks in advance
There might be issue because you initialised int i = 0 separately.
You can re-write code of line no.152 as shown below
for (int i = 0; i < storage.lenght; i++){
response = await addInventory(){
//Further code
}
}

Can I use Async inside Dart Isolate ??? its not working

I am using ImageEditor package to merge different images. below is my code. its working perfectly fine without using Isolate, when i use it with isolate, i get null error.
Working code without Isolate
startEditing() async {
for (var i = 0; i < image1.length || i == 0; i++) {
if (image1.isNotEmpty) {
img1 = await File(image1[i].path).readAsBytes();
}
for (var i = 0; i < image2.length || i == 0; i++) {
if (image2.isNotEmpty) {
img2 = await File(image2[i].path).readAsBytes();
}
final ImageEditorOption optionGroup = ImageEditorOption();
optionGroup.outputFormat = const OutputFormat.png(100);
optionGroup.addOptions([
MixImageOption(
x: 0,
y: 0,
width: 1000,
height: 1000,
target: MemoryImageSource(img1),
),
MixImageOption(
x: 0,
y: 0,
width: 1000,
height: 1000,
target: MemoryImageSource(img2),
),
]);
try {
final Uint8List? result = await ImageEditor.editImage(
image: mainImg, imageEditorOption: optionGroup);
if (result == null) {
image = null;
} else {
await saveImage(result, index);
setState(() {
image = MemoryImage(result);
index++;
});
}
} catch (e) {
print(e);
}
}
}
}
Code with Isolate not working
startEditing(SendPort sendPort) async {
for (var i = 0; i < image1.length || i == 0; i++) {
if (image1.isNotEmpty) {
img1 = await File(image1[i].path).readAsBytes();
}
for (var i = 0; i < image2.length || i == 0; i++) {
if (image2.isNotEmpty) {
img2 = await File(image2[i].path).readAsBytes();
}
final ImageEditorOption optionGroup = ImageEditorOption();
optionGroup.outputFormat = const OutputFormat.png(100);
optionGroup.addOptions([
MixImageOption(
x: 0,
y: 0,
width: 1000,
height: 1000,
target: MemoryImageSource(img1),
),
MixImageOption(
x: 0,
y: 0,
width: 1000,
height: 1000,
target: MemoryImageSource(img2),
),
]);
try {
final Uint8List? result = await ImageEditor.editImage(
image: mainImg, imageEditorOption: optionGroup);
if (result == null) {
image = null;
} else {
await saveImage(result, index);
image = MemoryImage(result);
index++;
sendPort.send(image);
}
} catch (e) {
print(e);
}
}
}
}
saveImage method
Future<String> saveImage(Uint8List bytes, int i) async {
final name = '${filenames[i]}';
final result = await ImageGallerySaver.saveImage(bytes, name: name);
print(result);
return result['filePath'];
}
Receiving in main thread
getImageas() async {
ReceivePort receiverPort =
ReceivePort();
final isolate =
await Isolate.spawn(startEditing, receiverPort.sendPort);
receiverPort.listen((data) {
print('Receiving: ' + data + ', ');
});
}
I get this error:
I/flutter (21937): Null check operator used on a null value
in this line:
final Uint8List? result = await ImageEditor.editImage(
image: mainImg, imageEditorOption: optionGroup);
I am sure that img1, img2, mainImg, image1, image2 values are not null... check 1000 times. I have also used flutter compute, and same result.
Flutter plugins that call into native code (such as image_editor) do not work in isolates spawned by Isolate.spawn.
The flutter_isolate package spawns isolates from native code for this reason. You should be able to use it to call image_editor in an isolate. (Disclaimer: I've never used flutter_isolate.)

Send string values from one smartphone device to another smartphone device via Bluetooth in flutter

I want to send multiple string values from one smartphone device to another device via Bluetooth in flutter. I have seen flutter_blue and flutter_bluetooth_searial package examples also but i cant find anything that sends multiple strings values via Bluetooth. can anyone please suggest how i can be able to achieve this task?
I used flutter_bluetooth_searial in one of my projects, here is the the whole class including: sending data (multiple strings), receiving data, connect, disconnect, auto-pairing, ...etc
Hope you find this helpful.
import 'dart:async';
import 'dart:typed_data';
import 'dart:convert' show utf8;
import 'package:flutter/foundation.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
class BluetoothStore extends ChangeNotifier {
var _instance = FlutterBluetoothSerial.instance;
var _dataBuffer = '';
void Function(String) _onDataCallback = (String data) {};
StreamSubscription<Uint8List> _dataSubscription;
StreamSubscription<BluetoothDiscoveryResult> _scannedDevicesSubscription;
BluetoothDiscoveryResult _connectedDevice;
BluetoothConnection _connection;
var name = "...";
var address = "...";
var pinNum = "1234";
var isScanning = false;
var _isConnecting = false;
var _autoPair = false;
var scannedDevices = List<BluetoothDiscoveryResult>();
var state = BluetoothState.UNKNOWN;
BluetoothStore() {
initBluetooth();
}
bool get autoPair => _autoPair;
bool get isConnecting => _isConnecting;
bool get isConnected => _dataSubscription != null;
set autoPair(bool value) {
_autoPair = value;
if (value) {
_instance.setPairingRequestHandler((request) {
if (request.pairingVariant == PairingVariant.Pin)
return Future.value(pinNum);
return Future.value("");
});
} else {
_instance.setPairingRequestHandler(null);
}
notifyListeners();
}
void initBluetooth() async {
// Get bluetooth initial state
this.state = await _instance.state;
this.address = await _instance.address;
this.name = await _instance.name;
notifyListeners();
_instance.onStateChanged().listen((state) {
this.state = state;
_reset();
});
}
Future<bool> pairWith(BluetoothDevice device) async {
var pairedDevices = await _instance.getBondedDevices();
if (pairedDevices.length < 7) {
var result = await _instance.bondDeviceAtAddress(device.address);
if (result) {
var deviceIndex = scannedDevices.indexWhere((scannedDevice) {
return scannedDevice.device.address == device.address;
});
scannedDevices[deviceIndex] = BluetoothDiscoveryResult(
device: BluetoothDevice(
name: device.name ?? '',
address: device.address,
type: device.type,
bondState:
result ? BluetoothBondState.bonded : BluetoothBondState.none,
),
rssi: scannedDevices[deviceIndex].rssi,
);
notifyListeners();
}
return Future.value(result);
}
return Future.value(false);
}
// Notice the return value
Future<bool> unpairFrom(BluetoothDevice device) async {
var result = await _instance.removeDeviceBondWithAddress(device.address);
if (result) {
var deviceIndex = scannedDevices.indexWhere((scannedDevice) {
return scannedDevice.device.address == device.address;
});
scannedDevices[deviceIndex] = BluetoothDiscoveryResult(
device: BluetoothDevice(
name: device.name ?? '',
address: device.address,
type: device.type,
bondState:
result ? BluetoothBondState.none : BluetoothBondState.bonded,
),
rssi: scannedDevices[deviceIndex].rssi,
);
notifyListeners();
}
return Future.value(result);
}
Future<bool> enable() => _instance.requestEnable();
Future<bool> disable() => _instance.requestDisable();
Future<void> openSettings() => _instance.openSettings();
Future<bool> connectTo(BluetoothDevice device) async {
_isConnecting = true;
if (isConnected) await _connection.close();
notifyListeners();
try {
var connection = await BluetoothConnection.toAddress(device.address);
_isConnecting = false;
_connection = connection;
_dataSubscription = connection.input.listen(_onDataReceived);
_dataSubscription.onDone(_onDisconnect);
var deviceIndex = scannedDevices.indexWhere((scannedDevice) {
return scannedDevice.device.address == device.address;
});
_connectedDevice = scannedDevices[deviceIndex] = BluetoothDiscoveryResult(
device: BluetoothDevice(
name: device.name ?? '',
address: device.address,
bondState: device.bondState,
type: device.type,
isConnected: true,
),
rssi: scannedDevices[deviceIndex].rssi,
);
notifyListeners();
return Future.value(true);
} catch (_) {
_isConnecting = false;
_dataSubscription = null;
_connection = null;
notifyListeners();
return Future.value(false);
}
}
Future<List<BluetoothDevice>> pairedDevices() async {
var result = await _instance.getBondedDevices();
return Future.value(result);
}
void disConnect() async {
if (isConnected) {
this.unpairFrom(_connectedDevice.device);
_connection.dispose();
}
}
void startScanning() {
isScanning = true;
scannedDevices.clear();
notifyListeners();
if (isConnected) scannedDevices.add(_connectedDevice);
_scannedDevicesSubscription = _instance.startDiscovery().listen((device) {
scannedDevices.add(device);
});
_scannedDevicesSubscription.onDone(() async {
isScanning = false;
notifyListeners();
});
}
void _onDataReceived(Uint8List data) {
// Allocate buffer for parsed data
var backspacesCounter = 0;
data.forEach((byte) {
if (byte == 8 || byte == 127) backspacesCounter++;
});
var buffer = Uint8List(data.length - backspacesCounter);
var bufferIndex = buffer.length;
// Apply backspace control character
backspacesCounter = 0;
for (int i = data.length - 1; i >= 0; i--) {
if (data[i] == 8 || data[i] == 127) {
backspacesCounter++;
} else {
if (backspacesCounter > 0) {
backspacesCounter--;
} else {
buffer[--bufferIndex] = data[i];
}
}
}
// Create message if there is new line character
var dataString = String.fromCharCodes(buffer);
var index = buffer.indexOf(13);
if (~index != 0) {
// \r\n
var data = backspacesCounter > 0
? _dataBuffer.substring(0, _dataBuffer.length - backspacesCounter)
: _dataBuffer = _dataBuffer + dataString.substring(0, index);
_onDataCallback(data);
_dataBuffer = dataString.substring(index);
} else {
_dataBuffer = (backspacesCounter > 0
? _dataBuffer.substring(0, _dataBuffer.length - backspacesCounter)
: _dataBuffer + dataString);
}
}
void _onDisconnect() {
// reset
if (this.state == BluetoothState.STATE_ON) {
var deviceIndex = scannedDevices.indexWhere((scannedDevice) {
return scannedDevice.device.address == _connectedDevice.device.address;
});
scannedDevices[deviceIndex] = BluetoothDiscoveryResult(
device: BluetoothDevice(
name: _connectedDevice.device.name ?? '',
address: _connectedDevice.device.address,
type: _connectedDevice.device.type,
bondState: _connectedDevice.device.bondState,
),
rssi: _connectedDevice.rssi,
);
}
_reset();
}
void _reset() {
_dataBuffer = '';
_isConnecting = false;
_dataSubscription = null;
_scannedDevicesSubscription = null;
_connectedDevice = null;
_connection = null;
if (this.state != BluetoothState.STATE_ON) {
scannedDevices.clear();
}
notifyListeners();
}
void onDataReceived(void Function(String) callback) {
_onDataCallback = callback;
}
bool sendData(String data) {
try {
data = data.trim();
if (data.length > 0 && isConnected) {
_connection.output.add(utf8.encode(data + "\r\n"));
return true;
}
} catch (e) {
return false;
}
return false;
}
void dispose() {
_instance.setPairingRequestHandler(null);
if (isConnected) _dataSubscription.cancel();
_scannedDevicesSubscription?.cancel();
super.dispose();
}
}
You can consume this class using ChangeNotifierProvider
ChangeNotifierProvider<BluetoothStore>.value(value: BluetoothStore())