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