1

I am trying to scan Android wifi networks and store them in array lists. My objective is as follows.

1.Scan wifi networks and store them in an ArrayList of ScanObject

private List<ScanResult> results; // A list of ScanResult is given by system
private ArrayList<ScanObject> scanObjectList = new ArrayList<ScanObject>;

for(int i=0;i<results.size();i++){
         String mac = results.get(i).BSSID;
         int rssi = results.get(i).level;
         scanObject = new ScanObject(mac,rssi);
         scanObjectList.add(i,scanObject);
}

2.Store the ArrayList of ScanObject in ScanInfo object with system time

    long systemTime = System.currentTimeMillis();
    scanInfo = new ScanInfo(systemTime,scanObjectList);

3.Add ScanInfo object into an ArrayList of ScanInfo objects

private ArrayList<ScanInfo> listOfScanInfoObjects = new ArrayList<ScanInfo>();
listOfScanInfoObjects.add(scanInfo);

When I try to display the objects in listOfScanInfoObjects, I can display I only see the last scan only. For example, If I do the following, after few scans, I see only the number of elements in the last object. All the others return me zero value. I would like to understand what I'm doing wrong here.

for(int q=0;q<listOfScanInfoObjects.size();q++) {
    System.out.println("SIZE: "+listOfScanInfoObjects.get(q).getScanObjects().size());
}

My ScanObject Class is as follows;

public class ScanObject {
private String BSSID; // MAC address of the AP
private int RSSI; // RSSI value in dBm

public ScanObject(String mac, int rssi) {
    setBSSID(mac);
    setRSSI(rssi);
    }
// setter methods
    public void setBSSID(String mac){
        this.BSSID = mac;
    }
    public void setRSSI(int rssi){
        this.RSSI = rssi;
    }
// getter methods
    public String getBSSID(){
        return this.BSSID;
   }
   public int getRSSI(){
        return this.RSSI;
   }
}

My ScanInfo Class is as follows;

public class ScanInfo {
   private long timeStamp;
   private ArrayList<ScanObject> scanObjectList;

   public ScanInfo(long time, ArrayList<ScanObject> scanList) {
      setTimeSamp(time);
      setScanObjects(scanList);
    }
   // setter methods
   public void setTimeSamp(long time){
      this.timeStamp = time;
   }
   public void setScanObjects(ArrayList<ScanObject> scanList){
      scanObjectList = new ArrayList<ScanObject>();
      this.scanObjectList = scanList;
   }

   // getter methods
   public long getTimeStamp(){
       return this.timeStamp;
   }
   public ArrayList<ScanObject> getScanObjects(){
       return this.scanObjectList;
   }
}

The following is the overall code.

public void main(){
  processRawResult();
  listOfScanInfoObjects.add(index,scanInfo);
  for(int q=0;q<listOfScanInfoObjects.size();q++) {
System.out.println("SIZE:"+listOfScanInfoObjects.get(q).getScanObjects().size());
        }

  scanObjectList.clear();
  index++;
}

// process results object
public void processRawResult(){
    long systemTime = System.currentTimeMillis();
    scanObjectList = new ArrayList<ScanObject>();
    for(int i=0;i<results.size();i++){
         String mac = results.get(i).BSSID;
         int rssi = results.get(i).level;
         scanObject = new ScanObject(mac,rssi);
         scanObjectList.add(i,scanObject);
    }
    scanInfo = new ScanInfo(systemTime,scanObjectList);
}

Thanks in advance.

13
  • Can you test the two list objects as a static which means a class variable? You might have several class objects, if you have different outcome after that. Commented Apr 20, 2018 at 5:26
  • can you please post code of storing scanInfo in list Commented Apr 20, 2018 at 5:28
  • Can you add the code for entire class where private ArrayList<ScanInfo> listOfScanInfoObjects = new ArrayList<ScanInfo>(); is used? Commented Apr 20, 2018 at 5:28
  • change scanObjectList.add(i,scanObject); to scanObjectList.add(scanObject); Commented Apr 20, 2018 at 5:37
  • 1
    @Hasala where are you incrementing index in listOfScanInfoObjects.add(index,scanInfo);? Commented Apr 20, 2018 at 5:48

3 Answers 3

1

@Hasala

 public void setScanObjects(ArrayList<ScanObject> scanList){
      scanObjectList = new ArrayList<ScanObject>();
      this.scanObjectList = scanList;
   }

Here you are referencing passed list here. So when you clear the list all data in scanObjectList the data contained in ScanInfo's list will also clear because both are same.

public void main(){
    final ScanInfo scanInfo = processRawResult();
    listOfScanInfoObjects.add(scanInfo);
    for(int q=0;q<listOfScanInfoObjects.size();q++) {
         System.out.println("SIZE:"+ listOfScanInfoObjects.get(q).getScanObjects().size());
     }

  scanObjectList.clear();
  index++;
}

So Instead of this.scanObjectList = scanList; use this.scanObjectList.addAll(scanList); in setScanObjects(ArrayList scanList) method.

Sign up to request clarification or add additional context in comments.

Comments

1

The problem is following code:

public void processRawResult(){
    long systemTime = System.currentTimeMillis();
    scanObjectList = new ArrayList<ScanObject>();
    for(int i=0;i<results.size();i++){
         String mac = results.get(i).BSSID;
         int rssi = results.get(i).level;
         scanObject = new ScanObject(mac,rssi);
         scanObjectList.add(i,scanObject);
    }
    scanInfo = new ScanInfo(systemTime,scanObjectList);
}

When you add an Object in ArrayList, you are adding its reference and not simply its value. Any change to the object will result in changes in the Object available in ArrayList.

In your case you are always reassigning the value of scanObjectList & scanInfo by two lines scanInfo = new ScanInfo(systemTime,scanObjectList); & scanObjectList = new ArrayList<ScanObject>();

Try following code:

public void main(){
    final ScanInfo scanInfo = processRawResult();
    listOfScanInfoObjects.add(scanInfo);
    for(int q=0;q<listOfScanInfoObjects.size();q++) {
System.out.println("SIZE:"+listOfScanInfoObjects.get(q).getScanObjects().size());
     }

  scanObjectList.clear();
  index++;
}

// process results object
public ScanInfo processRawResult(){
    long systemTime = System.currentTimeMillis();
    final ScanObject scanObjectList = new ArrayList<ScanObject>();
    for(int i=0;i<results.size();i++){
         String mac = results.get(i).BSSID;
         int rssi = results.get(i).level;
         scanObject = new ScanObject(mac,rssi);
         scanObjectList.add(i,scanObject);
    }
    return new ScanInfo(systemTime,scanObjectList);
}

1 Comment

Great! Thanks for updating
1

Here is my suggestion and assumption. I assumed that I have a class, ScanResultStore with some external information as follows:

class ScanResultStore {
    private List<ScanResult> results; // A list of ScanResult is given by
                                        // system
    private ArrayList<ScanObject> scanObjectList = new ArrayList<ScanObject>();
    private ArrayList<ScanInfo> listOfScanInfoObjects = new ArrayList<ScanInfo>();
    private int index = 0;
    ScanInfo scanInfo = null;

    public void setScanResult(List<ScanResult> results)
    {
        this.results = results;
    }

    public void main() {
        processRawResult();

        listOfScanInfoObjects.add(index++, scanInfo);
        for (int q = 0; q < listOfScanInfoObjects.size(); q++) {
            System.out.println("SIZE:" + listOfScanInfoObjects.get(q).getScanObjects().size());
        }

        scanObjectList.clear();
    }

    // process results object
    public void processRawResult() {
        long systemTime = System.currentTimeMillis();

        scanObjectList = new ArrayList<ScanObject>();
        for (int i = 0; i < results.size(); i++) {
            String mac = results.get(i).BSSID;
            int rssi = results.get(i).level;
            ScanObject scanObject = new ScanObject(mac, rssi);
            scanObjectList.add(i, scanObject);
        }

        scanInfo = new ScanInfo(systemTime, scanObjectList);
    }
}

I modified your class and add one method, setScanResult for the external information.

A ScanResult class looks like below,

class ScanResult {
    public String BSSID; // MAC address of the AP
    public int RSSI; // RSSI value in dBm
    public int level;
}

Then, we can have an entry point like similar one and the output will be

SIZE:3 SIZE:1

public static void main(String[] args)
{
    ScanResultStore clsStore = new ScanResultStore();
    List<ScanResult> results = new ArrayList<ScanResult>();

    ScanResult result1 = new ScanResult();
    result1.BSSID="AF-DF-CF-ED-EF";
    result1.RSSI=2;
    result1.level=4;
    results.add(result1);
    ScanResult result2 = new ScanResult();
    result2.BSSID="AD-DF-CF-ED-EF";
    result2.RSSI=1;
    result2.level=3;
    results.add(result2);
    ScanResult result3 = new ScanResult();
    result3.BSSID="AD-DG-CF-ED-EF";
    result3.RSSI=2;
    result3.level=5;
    results.add(result3);

    clsStore.setScanResult(results);

    clsStore.main();

    clsStore = new ScanResultStore();
    results = new ArrayList<ScanResult>();

    ScanResult result4 = new ScanResult();
    result3.BSSID="AD-DG-CF-ED-TF";
    result3.RSSI=1;
    result3.level=5;
    results.add(result4);

    clsStore.setScanResult(results);

    clsStore.main();
}

It's very clear that you have one ScanResultStore reference, it will be fine. You have 3 scan objects in the class, but you will have only one scan object after following code.

clsStore = new ScanResultStore(); results = new ArrayList();

ScanResult result4 = new ScanResult();
result3.BSSID="AD-DG-CF-ED-TF";
result3.RSSI=1;
result3.level=5;
results.add(result4);

clsStore.setScanResult(results);

clsStore.main();

I think you can watch your code carefully finding the case i described here.

Here is another case but the same output.

public static void main(String[] args)
{
    ScanResultStore clsStores[] = new ScanResultStore[2];

    List<ScanResult> results = new ArrayList<ScanResult>();

    ScanResult result1 = new ScanResult();
    result1.BSSID="AF-DF-CF-ED-EF";
    result1.RSSI=2;
    result1.level=4;
    results.add(result1);
    ScanResult result2 = new ScanResult();
    result2.BSSID="AD-DF-CF-ED-EF";
    result2.RSSI=1;
    result2.level=3;
    results.add(result2);
    ScanResult result3 = new ScanResult();
    result3.BSSID="AD-DG-CF-ED-EF";
    result3.RSSI=2;
    result3.level=5;
    results.add(result3);

    clsStores[0] = new ScanResultStore();

    clsStores[0].setScanResult(results);

    clsStores[0].main();

    clsStores[1] = new ScanResultStore();
    clsStores[1] = new ScanResultStore();
    results = new ArrayList<ScanResult>();

    ScanResult result4 = new ScanResult();
    result3.BSSID="AD-DG-CF-ED-TF";
    result3.RSSI=1;
    result3.level=5;
    results.add(result4);

    clsStores[1].setScanResult(results);

    clsStores[1].main();
}

Full source:

package com.tobee.tests.oop;

import java.util.ArrayList;
import java.util.List;

public class StaticNoStaticTest {

    public static void main(String[] args)
    {
        ScanResultStore clsStores[] = new ScanResultStore[2];

        List<ScanResult> results = new ArrayList<ScanResult>();

        ScanResult result1 = new ScanResult();
        result1.BSSID="AF-DF-CF-ED-EF";
        result1.RSSI=2;
        result1.level=4;
        results.add(result1);
        ScanResult result2 = new ScanResult();
        result2.BSSID="AD-DF-CF-ED-EF";
        result2.RSSI=1;
        result2.level=3;
        results.add(result2);
        ScanResult result3 = new ScanResult();
        result3.BSSID="AD-DG-CF-ED-EF";
        result3.RSSI=2;
        result3.level=5;
        results.add(result3);

        clsStores[0] = new ScanResultStore();

        clsStores[0].setScanResult(results);

        clsStores[0].main();

        clsStores[1] = new ScanResultStore();
        clsStores[1] = new ScanResultStore();
        results = new ArrayList<ScanResult>();

        ScanResult result4 = new ScanResult();
        result3.BSSID="AD-DG-CF-ED-TF";
        result3.RSSI=1;
        result3.level=5;
        results.add(result4);

        clsStores[1].setScanResult(results);

        clsStores[1].main();
    }

    public static void main2(String[] args)
    {
        ScanResultStore clsStore = new ScanResultStore();
        List<ScanResult> results = new ArrayList<ScanResult>();

        ScanResult result1 = new ScanResult();
        result1.BSSID="AF-DF-CF-ED-EF";
        result1.RSSI=2;
        result1.level=4;
        results.add(result1);
        ScanResult result2 = new ScanResult();
        result2.BSSID="AD-DF-CF-ED-EF";
        result2.RSSI=1;
        result2.level=3;
        results.add(result2);
        ScanResult result3 = new ScanResult();
        result3.BSSID="AD-DG-CF-ED-EF";
        result3.RSSI=2;
        result3.level=5;
        results.add(result3);

        clsStore.setScanResult(results);

        clsStore.main();

        clsStore = new ScanResultStore();
        results = new ArrayList<ScanResult>();

        ScanResult result4 = new ScanResult();
        result3.BSSID="AD-DG-CF-ED-TF";
        result3.RSSI=1;
        result3.level=5;
        results.add(result4);

        clsStore.setScanResult(results);

        clsStore.main();
    }
}

class ScanResult {
    public String BSSID; // MAC address of the AP
    public int RSSI; // RSSI value in dBm
    public int level;
}

class ScanResultStore {
    private List<ScanResult> results; // A list of ScanResult is given by
                                        // system
    private ArrayList<ScanObject> scanObjectList = new ArrayList<ScanObject>();
    private ArrayList<ScanInfo> listOfScanInfoObjects = new ArrayList<ScanInfo>();
    private int index = 0;
    ScanInfo scanInfo = null;

    public void setScanResult(List<ScanResult> results)
    {
        this.results = results;
    }

    public void main() {
        processRawResult();

        listOfScanInfoObjects.add(index++, scanInfo);
        for (int q = 0; q < listOfScanInfoObjects.size(); q++) {
            System.out.println("SIZE:" + listOfScanInfoObjects.get(q).getScanObjects().size());
        }

        scanObjectList.clear();
    }

    // process results object
    public void processRawResult() {
        long systemTime = System.currentTimeMillis();

        scanObjectList = new ArrayList<ScanObject>();
        for (int i = 0; i < results.size(); i++) {
            String mac = results.get(i).BSSID;
            int rssi = results.get(i).level;
            ScanObject scanObject = new ScanObject(mac, rssi);
            scanObjectList.add(i, scanObject);
        }

        scanInfo = new ScanInfo(systemTime, scanObjectList);
    }
}

class ScanObject {
    private String BSSID; // MAC address of the AP
    private int RSSI; // RSSI value in dBm

    public ScanObject(String mac, int rssi) {
        setBSSID(mac);
        setRSSI(rssi);
    }

    // setter methods
    public void setBSSID(String mac) {
        this.BSSID = mac;
    }

    public void setRSSI(int rssi) {
        this.RSSI = rssi;
    }

    // getter methods
    public String getBSSID() {
        return this.BSSID;
    }

    public int getRSSI() {
        return this.RSSI;
    }
}

class ScanInfo {
    private long timeStamp;
    private ArrayList<ScanObject> scanObjectList;

    public ScanInfo(long time, ArrayList<ScanObject> scanList) {
        setTimeSamp(time);
        setScanObjects(scanList);
    }

    // setter methods
    public void setTimeSamp(long time) {
        this.timeStamp = time;
    }

    public void setScanObjects(ArrayList<ScanObject> scanList) {
        scanObjectList = new ArrayList<ScanObject>();
        this.scanObjectList = scanList;
    }

    // getter methods
    public long getTimeStamp() {
        return this.timeStamp;
    }

    public ArrayList<ScanObject> getScanObjects() {
        return this.scanObjectList;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.