0

I'm fairly new to java but am trying to create an app that collects WiFi information periodically, displays it to the user and sends it to a database.

I have Wifi collection working, it collects the SSID, BSSID, RSSI and a timestamp. It displays it to the user and i can even send information to the server. ui

However, the current code i have does not send the data to the server correctly. It sends the data, but gets stuck on one SSID, BSSID and RSSI. For example if there are 20 wireless networks, the app would send 19 of the same entries and possibly have the next entry as the 20th. database

I believe it is something to do with the asynctask inside the function InsertData, perhaps it is running quicker than the wifithing function. But i am unsure how to resolve this.

Thanks for all responses!

Update

Hey all!

There are two functions being used here wifithing() and InsertData() which contains a async task for sending data to a mysql database, wifithing() works perfectly and assigns the SSID, BSSID and RSSI to a device to be displayed elsewhere, it does this in a loop to cycle through all the available networks.

Now InsertData() is called by the button press, and uses a loop to cycle through all the available networks. This does work, but am seeing some strange results on the database, first of all an duplicate entry is added at the beginning and secondly on the second button press no data is sent, on the third press it works, then on the fourth it doesn't.. database with duplicate

Edited wififragment.java

    package com.example.joe.ratscanner;


    import android.Manifest;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.content.pm.PackageManager;
    import android.net.wifi.ScanResult;
    import android.net.wifi.WifiManager;
    import android.os.AsyncTask;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.Toast;

    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicNameValuePair;

    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Timer;
    import java.util.TimerTask;
    import java.util.concurrent.Executor;

    //return inflater.inflate(R.layout.fragment_wifi, container, false);
    /**
     * A simple {@link Fragment} subclass.
     */
    public class wififragment extends Fragment {

        int count= 0;
        Timer t;
        String ServerURL = "http://ratscanner.duckdns.org/get_data.php" ;

        String TempWifi;
        String TempBSSID;
        String Templevel;
        String test;

        String isthishappening;


        TimerTask timer= new TimerTask(){

            @Override
            public void run() {

                getActivity().runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        //count--;
                        //if (count >= 0) {
                        if(count == 0) {


                            //Toast.makeText(getActivity(),"this updated",Toast.LENGTH_SHORT).show();
                              // wifithing();
                                //InsertData(); //probably remove this later


                        }
                    }
                });
                //if (count <= 0) {
                // t.cancel();
                //}
            }

        };





        public class device{
            CharSequence name;

            public String setName(CharSequence name) {
                this.name = name;
                return null;
            }

            public CharSequence getName (){
                return name;
            }
        }
        final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 125;
        List<ScanResult> wifiList;
        private WifiManager wifi;
        List<device> values = new ArrayList<device>();
        int netCount=0;
        int AnetCount=0;
        RecyclerView recyclerView;
        WifiScanAdapter wifiScanAdapter;

        public wififragment() {
            // Required empty public constructor
        }
        public static wififragment newInstance() {
            wififragment fragment = new wififragment();
            return fragment;
        }


        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }



        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            //Make instance of Wifi
            Button btnScan= (Button) getActivity().findViewById(R.id.wifiScan);
            wifi = (WifiManager) getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            //Check wifi enabled or not
            if (wifi.isWifiEnabled() == false)
            {
                Toast.makeText(getActivity(), "Wifi is disabled enabling...", Toast.LENGTH_LONG).show();
                wifi.setWifiEnabled(true);
            }
            //register Broadcast receiver
            getActivity().registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    wifiList=wifi.getScanResults();
                    netCount=wifiList.size();
                    AnetCount=wifiList.size();
                    // wifiScanAdapter.notifyDataSetChanged();
                    Log.d("Wifi","Total Wifi Network"+netCount);
                }
            },new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

            wifiScanAdapter=new WifiScanAdapter(values,getContext());
            recyclerView= (RecyclerView) getActivity().findViewById(R.id.wifiRecyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
            recyclerView.setAdapter(wifiScanAdapter);


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                checkandAskPermission();
            } else {
                wifithing();

            }

            btnScan.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    wifithing();
                    InsertData();
                    InsertData();
                    Toast.makeText(getContext(), netCount +"\n"+ AnetCount , Toast.LENGTH_SHORT).show();

                }

            });
        }

 /*       public void wifithing(){
            SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy");
            wifi.startScan();
            values.clear();

            try {
                netCount = netCount - 1;
                while (netCount >= 0) {
                    String currentDateTimeString = dateformat.getDateTimeInstance().format(new Date());
                    device d = new device();

                    d.setName(wifiList.get(netCount).SSID.toString()+"\n"+ wifiList.get(netCount).BSSID +" "+ wifiList.get(netCount).level +"\n" + currentDateTimeString );
                    //TempWifi = d;//returns nothing, need to make it return ssid

                    //TempWifi = "";// clears the old data
                    TempWifi = wifiList.get(netCount).SSID.toString(); //adds the new ssid
                    TempBSSID = wifiList.get(netCount).BSSID.toString(); //adds the new bssid
                    Templevel = Integer.toString(wifiList.get(netCount).level);// adds the new level

                    //currently have issue where one/two ssids are put in database
                    // maybe see how many "SSIDS" database recieves and how many show up on scan
                    // 20 on server, 20 on app
                    //20 on server, 20 on app
                    //19 on server, 19 on app

                    isthishappening = "This is from wifithing";
                    InsertData();// calls the method which sends the data to server

                    Log.d("WiFi",d.getName().toString());
                    values.add(d);
                    wifiScanAdapter.notifyDataSetChanged();
                    netCount=netCount -1;
                }
            }
            catch (Exception e){
                Log.d("Wifi", e.getMessage());
            }

        }*/
       public void wifithing(){
            SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy");
            wifi.startScan();
            values.clear();

            try {
                netCount = netCount - 1;
                while (netCount >= 0) {
                    String currentDateTimeString = dateformat.getDateTimeInstance().format(new Date());
                    device d = new device();

                    d.setName(wifiList.get(netCount).SSID.toString()+"\n"+ wifiList.get(netCount).BSSID +" "+ wifiList.get(netCount).level +"\n" + currentDateTimeString );
                    //TempWifi = d;//returns nothing, need to make it return ssid



                    //currently have issue where one/two ssids are put in database
                    // maybe see how many "SSIDS" database recieves and how many show up on scan
                    // 20 on server, 20 on app
                    //20 on server, 20 on app
                    //19 on server, 19 on app

                    isthishappening = "This is from wifithing";
                    //InsertData();// calls the method which sends the data to server

                    Log.d("WiFi",d.getName().toString());
                    values.add(d);
                    wifiScanAdapter.notifyDataSetChanged();
                    netCount=netCount -1;
                }
            }
            catch (Exception e){
                Log.d("Wifi", e.getMessage());
            }

        }





        //this code is responsible for sending data to the server through PHP////////////////////////////////////////////////////////
        public void InsertData(){

            class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {

                @Override
                protected String doInBackground(String... params) {

                    try {
                        AnetCount = AnetCount - 1;
                        while (AnetCount >= 0) {

                            TempWifi = wifiList.get(AnetCount).SSID.toString(); //adds the new ssid
                            TempBSSID = wifiList.get(AnetCount).BSSID.toString(); //adds the new bssid
                            Templevel = Integer.toString(wifiList.get(AnetCount).level);// adds the new level


                            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

                            nameValuePairs.add(new BasicNameValuePair("SSID", TempWifi));
                            nameValuePairs.add(new BasicNameValuePair("MAC", TempBSSID));
                            nameValuePairs.add(new BasicNameValuePair("level", Templevel));


                            try {
                                HttpClient httpClient = new DefaultHttpClient();

                                HttpPost httpPost = new HttpPost(ServerURL);

                                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                                HttpResponse httpResponse = httpClient.execute(httpPost);

                                HttpEntity httpEntity = httpResponse.getEntity();


                            } catch (ClientProtocolException e) {

                            } catch (IOException e) {

                            }

                            AnetCount = AnetCount - 1;

                        }


                    }
                    catch (Exception e){
                        Log.d("Wifi", e.getMessage());
                    }
                    return "Data Inserted Successfully";
                }
                @Override
                protected void onPostExecute(String result) {
                    isthishappening = "This is from async";
                    Log.d("wifi", isthishappening);

                    //Log.d("wifi", result);
                    super.onPostExecute(result);

                    //Toast.makeText(getContext(), TempWifi, Toast.LENGTH_SHORT).show();

                }
            }
            SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();

            sendPostReqAsyncTask.execute();

        }///////////////////////////////////////////////////////////////////////////////////////////////////////////////



        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {


            t = new Timer();
            t.scheduleAtFixedRate(timer , 10000 , 10000);
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_wifi, container, false);


        }

        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                               int[] grantResults) {
            switch (requestCode) {
                case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
                    Map<String, Integer> perms = new HashMap<String, Integer>();
                    perms.put(Manifest.permission.ACCESS_COARSE_LOCATION, PackageManager.PERMISSION_GRANTED);
                    for (int i = 0; i < permissions.length; i++)
                        perms.put(permissions[i], grantResults[i]);
                    if (perms.get(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        wifi.startScan();
                    } else {
                        // Permission Denied
                        Toast.makeText(getContext(), "Some Permission is Denied", Toast.LENGTH_SHORT)
                                .show();
                    }
                }
            }
        }

        private void checkandAskPermission() {
            List<String> permissionsNeeded = new ArrayList<String>();

            final List<String> permissionsList = new ArrayList<String>();
            if (!addPermission(permissionsList, Manifest.permission.ACCESS_COARSE_LOCATION))
                permissionsNeeded.add("Network");


            if (permissionsList.size() > 0) {
                if (permissionsNeeded.size() > 0) {
                    // Need Rationale
                    String message = "You need to grant access to " + permissionsNeeded.get(0);
                    for (int i = 0; i < permissionsNeeded.size(); i++)
                        message = message + ", " + permissionsNeeded.get(i);
                    showMessageOKCancel(message,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                                }
                            });
                    return;
                }

                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                return;
            }
            // initVideo();
        }

        private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
            new AlertDialog.Builder(getActivity())
                    .setMessage(message)
                    .setPositiveButton("OK", okListener)
                    .setNegativeButton("Cancel", okListener)
                    .create()
                    .show();
        }

        private boolean addPermission(List<String> permissionsList, String permission) {
            if (getActivity().checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                permissionsList.add(permission);
                if (!shouldShowRequestPermissionRationale(permission))
                    return false;
            }
            return true;
        }

        public void onDetach() {
            super.onDetach();
            count = 1;


            t.cancel();
            //timer was created at top of page as infinite, never cancelled even when the fragment closed -
            // t.cancel(): stops the timer and allows the page to switch without crashing
        }



    }

before code snippet from wififragment.java

public void wifithing(){
            SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy");
            wifi.startScan();
            values.clear();

            try {
                netCount = netCount - 1;
                while (netCount >= 0) {
                    String currentDateTimeString = dateformat.getDateTimeInstance().format(new Date());
                    device d = new device();

                    d.setName(wifiList.get(netCount).SSID.toString()+"\n"+ wifiList.get(netCount).BSSID +" "+ wifiList.get(netCount).level +"\n" + currentDateTimeString );
                    //TempWifi = d;//returns nothing, need to make it return ssid

                    //TempWifi = "";// clears the old data
                    TempWifi = wifiList.get(netCount).SSID.toString(); //adds the new ssid
                    TempBSSID = wifiList.get(netCount).BSSID.toString(); //adds the new bssid
                    Templevel = Integer.toString(wifiList.get(netCount).level);// adds the new level

                    //currently have issue where one/two ssids are put in database
                    // maybe see how many "SSIDS" database recieves and how many show up on scan
                    // 20 on server, 20 on app
                    //20 on server, 20 on app
                    //19 on server, 19 on app

                    InsertData();// calls the method which sends the data to server

                    Log.d("WiFi",d.getName().toString());
                    values.add(d);
                    wifiScanAdapter.notifyDataSetChanged();
                    netCount=netCount -1;
                    }
                }
            catch (Exception e){
                Log.d("Wifi", e.getMessage());
                }

        }




        //this code is responsible for sending data to the server through PHP////////////////////////////////////////////////////////
        public void InsertData(){

            class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
                @Override
                protected String doInBackground(String... params) {

                    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

                    nameValuePairs.add(new BasicNameValuePair("SSID", TempWifi));
                    nameValuePairs.add(new BasicNameValuePair("MAC", TempBSSID));
                    nameValuePairs.add(new BasicNameValuePair("level", Templevel));


                    try {
                        HttpClient httpClient = new DefaultHttpClient();

                        HttpPost httpPost = new HttpPost(ServerURL);

                        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                        HttpResponse httpResponse = httpClient.execute(httpPost);

                        HttpEntity httpEntity = httpResponse.getEntity();


                    } catch (ClientProtocolException e) {

                    } catch (IOException e) {

                    }

                    return "Data Inserted Successfully";
                }

                @Override
                protected void onPostExecute(String result) {

                    super.onPostExecute(result);

                    //Toast.makeText(getContext(), TempWifi, Toast.LENGTH_SHORT).show();

                }
            }
            SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();

            sendPostReqAsyncTask.execute();

        }///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  • Suggestion: Either make MAC address unique in the database or add a timestamp to your events (if you care about historical AP information) – OneCricketeer May 05 '18 at 15:21
  • Hi Cricket, Thanks for the suggestion! I am going to add a timestamp in the database but haven't added yet :L – Joe Hutchinson May 05 '18 at 15:36
  • Alright, well, my first thoughts here is that you're not waiting for the AsyncTask to finish before the `Log.d("WiFi",` line, where it looks like you're trying to fire off multiple database calls without queueing requests or catching the results ... I might suggest using a different network library such as OkHttp or Volley because those offer Callback interfaces out of the box and allow you to wait for a server response, and then continue with operations from there – OneCricketeer May 05 '18 at 15:49
  • You also have two empty catch blocks in the AsyncTask, so you are ignoring any errors that may be happening – OneCricketeer May 05 '18 at 15:50
  • Thanks, ill take a look! yeah i definitely think it is a issue with the AsyncTask, i'm not sure how a Callback interface would fit in to this code, as i don't understand them properly.perhaps like this https://www.javaworld.com/article/2077462/learn-java/java-tip-10--implement-callback-routines-in-java.html – Joe Hutchinson May 05 '18 at 16:01
  • See this example. https://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a – OneCricketeer May 05 '18 at 17:18
  • hey cricket, sorry i cant figure out how to use the callback interface here, from what i see the InsertData() async function that send the data is being run after the wifithing() function, meaning they all are set to the same result. how can i use a call back interface to make wifithing() wait till InsertData() has succesfully sent? – Joe Hutchinson May 06 '18 at 13:25
  • It would look something like `insertData(new OnDataInsertedListener() { // do something })` Where you could define that interface however you want to in terms of methods within it, depending on how the parameter to the insertData method is used. Very similar to the onClick or onReceive events you've already defined elsewhere – OneCricketeer May 06 '18 at 16:37

0 Answers0