Search code examples
javaandroidlistout-of-memorywifimanager

Problems with Out of memory error


I get out of memory error if the function doesWifiExist is false if it is true every thing works normally.Can someone tell me what m i doing wrong

The idea is to get a list of wifi networks nearby and check if the inserted network exists in the list.

Here is the wifi network scanning code and the the function that checks if the wifi network exists.

MainActivity:

    private WiFiConnection _wifiConnection = null;
    static final int MY_PERMISSIONS_REQUEST = 1042;
    private static final String PERMISSIONS_TAG = "PERMISSION";
    ...
   @Override
    protected void onStart() {
        super.onStart();
        _wifiConnection = new WiFiConnection(this);
        startScan();
    }

    @Override
    protected void onStop() {
        super.onStop();

        _wifiConnection.stopScan();
        unregisterReceiver(_wifiScanReceiver);
    }

    void startScan() {
        checkPermission(this);

        registerReceiver(_wifiScanReceiver,
                new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        Thread t = new Thread(_wifiConnection.getWifiScanner());
        t.start();
    }

    private final BroadcastReceiver _wifiScanReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent intent) {
            if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                if (_wifiConnection != null && _wifiConnection.isWifiEnabled()) {
                    _wifiConnection.updateScanData();
                }

            }
        }
    };


    public static boolean checkPermission(Activity activity) {
        boolean permission = true;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<String> requiringList = new ArrayList<>();
            permission = activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
            Log.d(PERMISSIONS_TAG, "ACCESS_COARSE_LOCATION: " + permission);
            if (!permission) {
                requiringList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
            }

            if (requiringList.size() > 0) {
                String[] stringArray = requiringList.toArray(new String[0]);
                activity.requestPermissions(stringArray, MY_PERMISSIONS_REQUEST);
            }
        }
        return permission;
    }

    private boolean doesWifiExist(String s){
            String[] array = s.split(" ");
            String ssid = array[0];
            boolean flag = false;
            //Check if wifi exists in the area
            for(int i = 0 ; i < _wifiConnection.getListSSIDs().size(); i++){
                if(_wifiConnection.getListSSIDs().get(i).equals(ssid)){
                    flag = true;
                    break;
                }
            }
            return flag;
        }

WiFiConnection class:

public class WiFiConnection
    {
        private static final int SCAN_INTERVAL = 5000;

        final private List<String> _listSSIDs = new ArrayList<>();

        private WifiManager _wifiManager;

        private final WiFiScanner _startScan = new WiFiScanner();
        private List<ScanResult> scanResults;

        WiFiConnection(Activity activity) {
            _wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        }

        //Puts wifi networks in a list
        public List<String> getListSSIDs() {

            for(int i = 0; i < scanResults.size(); i++)
            {
                _listSSIDs.add(scanResults.get(i).SSID);
            }
            return _listSSIDs;

        }
        WiFiScanner getWifiScanner() { return _startScan; }
        void stopScan() { _startScan.stop(); }

        boolean isWifiEnabled() { return _wifiManager.isWifiEnabled(); }

        //Gets the wifi networks
        void updateScanData() {
            if ((_wifiManager != null && _wifiManager.isWifiEnabled())) {
                scanResults = _wifiManager.getScanResults();
            }
        }

        //Scans at an interval
        private class WiFiScanner implements Runnable
        {
            private boolean _stop = false;
            public void stop() {_stop = true;}
            @Override
            public void run() {
                while (!_stop) {
                    _listSSIDs.clear();
                    _wifiManager.startScan();
                    try {
                        Thread.sleep(SCAN_INTERVAL);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

The code where doesWifiExist is used.

 //Check if wifi exists in the area
 if(doesWifiExist(barcode.displayValue)){
   //Connects to wifi
   WifiConnect(barcode.displayValue);
   //Saves item in db
   insertItem();

   if(networkSecurity.equals("None")){
      networkPass = empty;
   }
   //Adds item to recyclerview
   historyItems.add(0, new HistoryItem(wifiName + " " + networkSSID, wifiPass + " " + networkPass));
   adapter.notifyItemInserted(0);
 } else
       Snackbar.make(findViewById(R.id.main_activity), R.string.snackInvalidQrCode, Snackbar.LENGTH_SHORT).show();

Solution

  • This method is called many times, and it everytime adds all scanResults at the end of field _listSSIDS.

       public List<String> getListSSIDs() {
            for(int i = 0; i < scanResults.size(); i++)
            {
                _listSSIDs.add(scanResults.get(i).SSID);
            }
            return _listSSIDs;
        }
    

    Use a local variable with a new List or better Set there.

    Instead replace

            for(int i = 0 ; i < _wifiConnection.getListSSIDs().size(); i++){
                if(_wifiConnection.getListSSIDs().get(i).equals(ssid)){
                    flag = true;
                    break;
                }
            }
    

    with

            flag = _wifiConnection.hasSSID(String ssid);
    
      public boolean hasSSID(String ssid) {
            for (int i = 0; i < scanResults.size(); i++) {
                if (ssid.equals(scanResults.get(i).SSID)) {
                    return true;
                }
            }
            return false;
        }