0

I've been researching this logic from the past week but no luck. Can anyone help me on with it? So the problem where I got stuck is I'm using the beacon concept (Moko Beacon) using bindService where it Scans the beacons till the app has been destroyed. So I get the beacon data all the time.

Here's my code:

public class MainActivity extends AppCompatActivity implements 
              MokoScanDeviceCallback {

private MokoService mMokoService;
private HashMap<String, BeaconXInfo> beaconXInfoHashMap;
public ArrayList<BeaconXInfo> beaconXInfos;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
    beaconXInfoHashMap = new HashMap<>();
    beaconXInfos = new ArrayList<>();

}

public void onScanDevice(DeviceInfo device) {
    final BeaconXInfo beaconXInfo = beaconXInfoParseable.parseDeviceInfo(device);
    if (beaconXInfo == null) {
        return;
    }
    beaconXInfoHashMap.put(beaconXInfo.mac, beaconXInfo);
    updateDevices();
}

private void updateDevices() {
Collections.sort(beaconXInfos, new Comparator<BeaconXInfo>() {
        @Override
        public int compare(BeaconXInfo lhs, BeaconXInfo rhs) {

           Log.e("beaconXinfo", String.valueOf(beaconXInfos.toString())); 

            if (lhs.rssi < rhs.rssi){

                for (int i = 0 ; i < beaconXInfos.size();i++){

                    if ((beaconXInfos.get(i).rssi > -40)){
                        NotificationHelper notificationHelper = new NotificationHelper(MainActivity.this);
                        notificationHelper.CreateNotification(beaconXInfos.get(i).mac,"enter");
                    }else if ((beaconXInfos.get(i).rssi < -40)){
                        NotificationHelper notificationHelper = new NotificationHelper(MainActivity.this);
                        notificationHelper.CreateNotification(beaconXInfos.get(i).mac,"exit");
                    }
                }
            }

            return 0;
        }
    });
    }

The problem lies in the updateDevices() method where I get values continuously till I destroy the app. The log values are as below :

E/beaconXinfo: [BeaconXInfo{name='BeaconX', mac='F5:5E:B1:65:94:4B'}]
E/beaconXinfo: [BeaconXInfo{name='BeaconX', mac='F5:5E:B1:65:94:4B'}, BeaconXInfo{name='UFO', mac='55:46:4F:D2:72:5A'}]
E/beaconXinfo: [BeaconXInfo{name='BeaconX', mac='F5:5E:B1:65:94:4B'}, BeaconXInfo{name='UFO', mac='55:46:4F:D2:72:5A'}, BeaconXInfo{name='null', mac='C8:DE:FE:45:50:02'}] //change in the data

As you can see above there is a change in data in the last log I want to send the data to the server only when there is a change in data in the hashmap.

So first I send the data "F5:5E:B1:65:94:4B" because there is only one value. Next, I need to compare this hashmap with the next hashmap where there's a change in the data called "55:46:4F:D2:72:5A". I need to send this data ignoring the "F5:5E:B1:65:94:4B".

Like same, How to send only this "C8:DE:FE:45:50:02" value comparing with the previous hashmap to the server.

So How to compare the first log of hashmap data with the next series of hashmap data where I can take only the latest value and send it to the server.

I've researched a bunch of question before posting this like below:

How to remove Duplicate value from arraylist in Android

How do I remove repeated elements from ArrayList?

Remove duplicate values from HashMap in Java

Maybe I might be confused with the above which I use in my code.

If anything needs to be added into the code please comment below. Any suggestion and answers would be highly appreciated. Thanks in advance.

Brahma Datta
  • 1,102
  • 1
  • 12
  • 20

2 Answers2

1

The easiest way would be to first split your beaconXinfo. Not sure how to do that, but you can either deserialize it or else use regular expressions to break them down and extract the MAC address.

Once that you have a list of MAC addresses (or a means to iterate over them), use a HashSet, which exposes a method called contains, which allows you to check if a string is already present within the set.

If the string is not present in the set, then it means that this is something new, and you need to send it to the server. If it exists, then, it means that you have already seen that string, and that there is no need to send it.

npinti
  • 51,780
  • 5
  • 72
  • 96
  • That's a great idea. But for every scan, I get the repeated mac address with another hashmp so Does your idea works there? @npinti – Brahma Datta May 13 '19 at 08:32
  • I'm getting beaconXInfoHashMap data as beacxonhashmap: {F5:5E:B1:65:94:4B=BeaconXInfo{name='BeaconX', mac='F5:5E:B1:65:94:4B'}, 55:46:4F:D2:72:5A=BeaconXInfo{name='UFO', mac='55:46:4F:D2:72:5A'}, C8:DE:FE:45:50:02=BeaconXInfo{name='null', mac='C8:DE:FE:45:50:02'}}.How to get the mac value from it? – – Brahma Datta May 13 '19 at 10:43
  • @g.brahma Datta: you can persist the Set. I am not aware of how you have implemented the whole thing, so you can either keep it in memory or save it to a file. – npinti May 13 '19 at 16:25
  • 1
    I got the data what I was waiting for @npinti. Thank you for your valuable suggestion – Brahma Datta May 13 '19 at 17:02
1

Why don't you, everytime you scan for a device, check if it exists then send it otherwise ?

public void onScanDevice(DeviceInfo device) {
    final BeaconXInfo beaconXInfo = beaconXInfoParseable.parseDeviceInfo(device);
    if (beaconXInfo == null) {
        return;
    }
    if (!beaconXInfoHashMap.containsKey(beaconXInfo.mac)) {
        // new, send it
    }
    beaconXInfoHashMap.put(beaconXInfo.mac, beaconXInfo);
    updateDevices();
}
Ali Ben Zarrouk
  • 1,891
  • 16
  • 24
  • Hey, thanks for quick reply. I'll try it . Thanks a lot @Ali – Brahma Datta May 13 '19 at 08:30
  • I'm getting beaconXInfoHashMap data as beacxonhashmap: {F5:5E:B1:65:94:4B=BeaconXInfo{name='BeaconX', mac='F5:5E:B1:65:94:4B'}, 55:46:4F:D2:72:5A=BeaconXInfo{name='UFO', mac='55:46:4F:D2:72:5A'}, C8:DE:FE:45:50:02=BeaconXInfo{name='null', mac='C8:DE:FE:45:50:02'}}.How to get the mac value from it? – Brahma Datta May 13 '19 at 10:33
  • I dont understand, where do you get it ? and the hashmap key is the mac address in your case for beaconXInfoHashMap. – Ali Ben Zarrouk May 13 '19 at 10:44
  • I got that when i put the beaconXInfo's mac address in the beaconXInfoHashMap @Ali – Brahma Datta May 13 '19 at 10:46
  • Before doing `beaconXInfoHashMap.put(beaconXInfo.mac, beaconXInfo);` you already know if its a new mac address or not. And you also have the mac address being `beaconXInfo.mac` – Ali Ben Zarrouk May 13 '19 at 10:52
  • So you are telling me to send the data to server if that condition is a success? @Ali – Brahma Datta May 13 '19 at 10:53
  • `(!beaconXInfoHashMap.containsKey(beaconXInfo.mac)) ` this condition means that the new found mac address doesnt exist in your hashmap, encountered the first time, and thus you have to send it. – Ali Ben Zarrouk May 13 '19 at 10:54
  • 1
    Ok I'll send that @Ali – Brahma Datta May 13 '19 at 10:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/193253/discussion-between-ali-ben-zarrouk-and-g-brahma-datta). – Ali Ben Zarrouk May 13 '19 at 11:14