alann-maulana / flutter_beacon

An hybrid iBeacon scanner and transmitter SDK for Flutter Android and iOS.
Apache License 2.0
117 stars 144 forks source link

Changing to default when you go away from Beacon #27

Closed MapiFer closed 4 years ago

MapiFer commented 4 years ago

Hi,

I want to thank you for this great plugin. I'm using it with great success, but I have a little problem: I have a text that said "Unknow" while I'm away from any becon, and said some area name when I listen some beacon. The problem was that when I go away after chnge the text from Unknow to the area name, it keep as that area until I find another beacon. I want it to chnge back to unknow if there are no beacons near.

I change my code and now it works as I want, when I go away the text come back to Unknow. My problem now is that when I'm near a becon, it dont keep the text even if I don´t move, it start to change from Unknow to Area Name. This is my code, hope someone can tell me what I'm doing wrong:

    _streamRanging = flutterBeacon.ranging(regions).listen((result) {
      if (result != null && mounted) {

        _regionBeacons[result.region] = result.beacons;
        _beacons.clear();
        if (result.beacons.length == 0 && globals.Minor != 0){
          setState(() {
            globals.Minor = 0;
            globals.Ubicado = "Desconocida";
            globals.codArea = '0';
            globals.Sucio = false;
            globals.Limpio = false;
          });
        }
        _regionBeacons.values.forEach((list) {
          _beacons.addAll(list);
          if (_beacons[0].minor != globals.Minor){
            globals.Minor = _beacons[0].minor;
            BuscarArea(globals.Minor);
          }
          _beacons.sort(_compareParameters);
        });
      }
    });
alann-maulana commented 4 years ago

Hi @MapiFer

This is like my current issue from my project within past few months ago, this is happen especially in Android. I am solving it by saving the last detected timestamp of a beacon, then adding some threshold constant. So I will remove the beacon from a List only when the last detected timestamp past the threshold.

import 'package:flutter_beacon/flutter_beacon.dart' as fb;

// equal to 15 seconds
const kThresholdLastDetected = 15000;

class MyBeacon {
  MyBeacon(this._beacon, {DateTime lastTimestamp})
      : _lastTimestamp = lastTimestamp ?? DateTime.now();

  fb.Beacon _beacon;
  fb.Beacon get beacon => _beacon;

  DateTime _lastTimestamp;
  DateTime get lastTimestamp => _lastTimestamp;

  bool needToRemoved(DateTime timestamp) =>
      timestamp.millisecondsSinceEpoch - _lastTimestamp.millisecondsSinceEpoch >
      kThresholdLastDetected;

  void updateBeaconIfEqual(fb.Beacon beacon) {
    if (_beacon.proximityUUID == beacon.proximityUUID &&
        _beacon.major == beacon.major &&
        _beacon.minor == beacon.minor) {
      _beacon = beacon;
      _lastTimestamp = DateTime.now();
    }
  }
}

Call updateBeaconIfEqual after getting a ranging result on each beacon found. Then iterate again and call needToRemoved to check if there are some beacon needs to remove from list.

Hope it can help.

MapiFer commented 4 years ago

that ws great, it totally works for me.