0

Hey guys ive been working on a project to create a type of wifi hot spot manager, so that it records the connected devices with mac address, ip address and other information. However i can't seem to work out as to why when i press get Clients from screen it doesn't gather any data of whos connected. I have compiled the file to an APK to test on my phone seeing as wifi functionality does not work on the emulator in android studio.

Credit for the code goes to:

1) Android 2.3 wifi hotspot API

2) https://www.whitebyte.info/android/android-wifi-hotspot-manager-class

package com.example.gavin.wifiattendance;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.nfc.Tag;
import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.logging.LogRecord;
import android.os.Handler;

/**
 * Created by Gavins on 05/03/2015.
 */
public class AccessPoint extends Activity {
    private static int constant = 0;
    private Context context;

    private static int WIFI_STATE_UNKNOWN = -1;
    private static int WIFI_STATE_DISABLING = 0;
    private static int WIFI_STATE_DISABLED = 1;
    public static int WIFI_STATE_ENABLING = 2;
    public static int WIFI_STATE_ENABLED = 3;
    private static int WIFI_STATE_FAILED = 4;

    final static String[] WIFI_STATE_TEXTSTATE = new String[]{
            "DISABLING","DISABLED","ENABLING","ENABLED","FAILED"
    };

    private WifiManager wifi;
    private String TAG = "WifiAP";

    private int stateWifi = -1;
    private boolean alwaysEnabledWifi = true;


    //enable or disable the wifi
    public void toggleWifiAP(WifiManager wifiHandler, Context context){
        if (wifi == null){
            wifi = wifiHandler;
        }
        boolean wifiApIsOn = getWifiApState() == WIFI_STATE_ENABLED || getWifiApState()==WIFI_STATE_ENABLING;
        new SetWifiApTask(!wifiApIsOn, false, context).execute();
    }

    private int setWifiApEnabled(boolean enabled){
        Log.d(TAG, "Set wifi enabled called" + enabled);

        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "Attend Lecture";
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

        //remember wireless state
        if (enabled && stateWifi == -1){
            stateWifi = wifi.getWifiState();
        }

        //disable the wireless
        if (enabled && wifi.getConnectionInfo() !=null){
            Log.d(TAG, "disable wifi: calling");
            wifi.setWifiEnabled(false);
            int loopMax = 10;
            while (loopMax > 0 && wifi.getWifiState() != WifiManager.WIFI_STATE_DISABLED){
                Log.d(TAG, "Disable Wifi: Waiting, pass:" + (10-loopMax));
                try{
                    Thread.sleep(500);
                    loopMax--;
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            Log.d(TAG, "Disabling wifi is done, pass: " + (10-loopMax));
        }

        //enable and disable wifi AP
        int state = WIFI_STATE_UNKNOWN;
        try {
            Log.d(TAG, (enabled?"enabling":"Disabling")+"wifi ap: calling");
            wifi.setWifiEnabled(false);
            Method method1 = wifi.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
            method1.invoke(wifi, config, enabled);
            Method method2 = wifi.getClass().getMethod("getWifiState");
            state = (Integer)method2.invoke(wifi);
        }catch (Exception e){
            //Log.e(WIFI_SERVICE, e.getMessage());
        }

        //Use thread while processing occurs
        if (!enabled){
            int loopMax = 10;
            while (loopMax>0 && (getWifiApState()==WIFI_STATE_DISABLING || getWifiApState()==WIFI_STATE_ENABLED || getWifiApState()==WIFI_STATE_FAILED)){
                Log.d(TAG, (enabled?"enabling": "disabling")+ "wifi AP: waiting, pass:" + (10-loopMax));
                try {
                    Thread.sleep(500);
                    loopMax--;
                }catch (Exception e){

                }
            }
            Log.d(TAG, (enabled?"enabling":"disabling")+" Wifi ap: done, pass: " + (10-loopMax));

            //enable the wifi
            if (stateWifi==WifiManager.WIFI_STATE_ENABLED || stateWifi==WifiManager.WIFI_STATE_ENABLING || stateWifi==WifiManager.WIFI_STATE_UNKNOWN || alwaysEnabledWifi){
                Log.d(TAG, "enable wifi: Calling");
                wifi.setWifiEnabled(true);
                //this way it doesnt hold things up and waits for it to get enabled
            }

            stateWifi = -1;
        }else if (enabled){
            int loopMax = 10;
            while (loopMax>0 && (getWifiApState()==WIFI_STATE_ENABLING || getWifiApState()==WIFI_STATE_DISABLED || getWifiApState()==WIFI_STATE_FAILED)){
                Log.d(TAG, (enabled?"Enabling": "disabling") + "wifi ap: waiting, pass: " + (10-loopMax));
                try{
                    Thread.sleep(500);
                    loopMax--;
                }catch (Exception e){

                }
            }
            Log.d(TAG, (enabled?"Enabling": "disabling")+ "wifi ap: done, pass: " + (10-loopMax));
        }
        return state;
    }

    //Get the wifi AP state
    public int getWifiApState(){
        int state = WIFI_STATE_UNKNOWN;
        try {
            Method method2 = wifi.getClass().getMethod("getWifiApState");
            state = (Integer) method2.invoke(wifi);
        }catch (Exception e){

        }

        if (state>=10){
            constant=10;
        }

        WIFI_STATE_DISABLING = 0+constant;
        WIFI_STATE_DISABLED = 1+constant;
        WIFI_STATE_ENABLING = 2+constant;
        WIFI_STATE_ENABLED = 3+constant;
        WIFI_STATE_FAILED = 4+constant;

        Log.d(TAG, "getWifiApState " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state-constant]));
        return state;
    }

    class SetWifiApTask extends AsyncTask<Void, Void, Void>{
        boolean mMode;
        boolean mFinish;
        ProgressDialog pDialog;

        public SetWifiApTask(boolean mode, boolean finish, Context context){
            mMode = mode;
            mFinish = finish;
            pDialog = new ProgressDialog(context);
        }

        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            pDialog.setTitle("Turning on Access Point " + (mMode?"On":"Off" + "..."));
            pDialog.setMessage("Please wait a moment...");
            pDialog.show();
        }

        @Override
        protected void onPostExecute(Void aVoid){
            super.onPostExecute(aVoid);
            try {
                pDialog.dismiss();
                MainActivity.updateStatusDisplay();
            }catch (IllegalArgumentException e){

            };
            if (mFinish){
                finish();
            }
        }

        @Override
        protected Void doInBackground(Void... params) {
            setWifiApEnabled(mMode);
            return null;
        }
    }

    //get the list connected to the wifi hotspot
    public void getClientList(boolean onlyReachable, FinishScanListener finishListener){
        getClientList(onlyReachable, 300, finishListener);
    }

    public void getClientList(final boolean onlyReachable, final int reachableTimeout, final FinishScanListener finishListener){

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                BufferedReader br = null;
                final ArrayList<ClientScanResult> result = new ArrayList<>();

                try {
                    br = new BufferedReader(new FileReader("/proc/net/arp"));
                    String line;
                    while ((line = br.readLine()) != null){
                        String[] splitted = line.split(" +");

                        if ((splitted !=null) && (splitted.length >=4)){
                            String mac = splitted[3];

                            if (mac.matches("..:..:..:..:..:..")){
                                boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);

                                if (!onlyReachable || isReachable){
                                    result.add(new ClientScanResult(splitted[0], splitted[3], splitted[5], isReachable));
                                }
                            }
                        }
                    }
                }catch (Exception e){
                    Log.e(this.getClass().toString(), e.toString());
                }finally {
                    try {
                        br.close();
                    }catch (IOException e){
                        Log.e(this.getClass().toString(), e.getMessage());
                    }
                }
                //Get handler that will be used to post to main thread
                Handler mainHandler = new Handler(context.getMainLooper());
                Runnable myRunnable = new Runnable() {
                    @Override
                    public void run() {
                        finishListener.onFinishScan(result);
                    }
                };
                mainHandler.post(myRunnable);
            }
        };

        Thread myThread = new Thread(runnable);
        myThread.start();

    }


}

and here is the main activity file:

    package com.example.gavin.wifiattendance;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import com.example.gavin.wifiattendance.AccessPoint;

import java.util.ArrayList;

public class MainActivity extends ActionBarActivity{

    boolean wasApEnabled = false;
    static AccessPoint wifiAP;
    private WifiManager wifi;
    static Button apButton;
    static TextView textView;

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

        apButton = (Button) findViewById(R.id.toggleBtn);
        textView = (TextView) findViewById(R.id.wifiClients);

        wifiAP = new AccessPoint();
        wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

        scan();

        apButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                wifiAP.toggleWifiAP(wifi, MainActivity.this);
            }
        });

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_DIM_BEHIND);

    }

    public void scan(){
        wifiAP.getClientList(false, new FinishScanListener() {
            @Override
            public void onFinishScan(final ArrayList<ClientScanResult> clients) {
                textView.setText("WifiApState:" + wifiAP.getWifiApState()+ "\n\n");
                textView.append("Clients: \n");
                for (ClientScanResult clientScanResult : clients){
                    textView.append("====================\n");
                    textView.append("ipAddress: " + clientScanResult.getIpAddress() + "\n");
                    textView.append("Device: " + clientScanResult.getDevice() + "\n");
                    textView.append("macAddress: " + clientScanResult.getMacAddress() + "\n");
                    textView.append("isReachable: " + clientScanResult.isReachable() + "\n");

                }
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        if (wasApEnabled) {
            if (wifiAP.getWifiApState() != wifiAP.WIFI_STATE_ENABLED && wifiAP.getWifiApState() != wifiAP.WIFI_STATE_ENABLING) {
                wifiAP.toggleWifiAP(wifi, MainActivity.this);
            }
        }
        updateStatusDisplay();
    }

    @Override
    public void onPause() {
        super.onPause();
        boolean wifiApIsOn = wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLED || wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLING;
        if (wifiApIsOn){
            wasApEnabled = true;
            wifiAP.toggleWifiAP(wifi, MainActivity.this);
        }else {
            wasApEnabled = false;
        }
        updateStatusDisplay();
    }

    public static void updateStatusDisplay(){
        if (wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLED || wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLING){
            apButton.setText("Turn Off");
        }else {
            apButton.setText("Turn on");
        }
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0,0,0, "Get Clients");
        return super.onCreateOptionsMenu(menu);
    }

    public boolean onOptionsItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()){
            case 0:
                scan();
                break;
        }
        return super.onMenuItemSelected(featureId, item);
    }
}

Edit: commented out the main looper made it work but after taking out the comments, the application now crashes on launch

http://gyazo.com/fa068fd1fce3f27f43185c0cd12568c1

Community
  • 1
  • 1
hero8110
  • 259
  • 4
  • 5
  • 14
  • post your logcat errors –  Mar 07 '15 at 20:18
  • The funny thing is there isn't any errors so I'm not sure What else I could show – hero8110 Mar 07 '15 at 23:20
  • ok , you can give Log.d("main","...") . just print your Log after any code that you trust code work fine –  Mar 08 '15 at 08:04
  • Hmm i think it works but doesn't work at the same time is because i commented out the main handler, so when i uncomment it the application does not start any more. Ill re edit my code above, and ill post the log cat – hero8110 Mar 08 '15 at 14:30
  • Hey eddy ive posted up the log cat file and taken out the comments from the main looper at the bottom of the access point class – hero8110 Mar 08 '15 at 15:25

0 Answers0