Android Wifi Hotspot Manager Class

Android has the great option to let you Tether your connection via wifi, but as developer you got little to none control over this mechanism.

Therefore i wrote a class to correct this: WifiApManager.

With this class you can enable the check the current Status of the Hotspot, enable/disable it, get/set the current AP configuration and also get the list of currently connected clients.

 

I also made an example to demonstrate it’s capabilities:

 

Download example Sourcecode

The Code is hosted on github: https://github.com/nickrussler/Android-Wifi-Hotspot-Manager-Class

 

And here the source-code of the class WifiApManager.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 * Copyright 2013 WhiteByte (Nick Russler, Ahmet Yueksektepe).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package com.whitebyte.wifihotspotutils;
 
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 android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.util.Log;
 
public class WifiApManager {
  private final WifiManager mWifiManager;
  private Context context;
 
  public WifiApManager(Context context) {
    this.context = context;
    mWifiManager = (WifiManager) this.context.getSystemService(Context.WIFI_SERVICE);
  }
 
  /**
   * Start AccessPoint mode with the specified
   * configuration. If the radio is already running in
   * AP mode, update the new configuration
   * Note that starting in access point mode disables station
   * mode operation
   * @param wifiConfig SSID, security and channel details as part of WifiConfiguration
   * @return {@code true} if the operation succeeds, {@code false} otherwise
   */
  public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
    try {
      if (enabled) { // disable WiFi in any case
        mWifiManager.setWifiEnabled(false);
      }
 
      Method method = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
      return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
    } catch (Exception e) {
      Log.e(this.getClass().toString(), "", e);
      return false;
    }
  }
 
  /**
   * Gets the Wi-Fi enabled state.
   * @return {@link WIFI_AP_STATE}
   * @see #isWifiApEnabled()
   */
  public WIFI_AP_STATE getWifiApState() {
    try {
      Method method = mWifiManager.getClass().getMethod("getWifiApState");
 
      int tmp = ((Integer)method.invoke(mWifiManager));
 
      // Fix for Android 4
      if (tmp >= 10) {
        tmp = tmp - 10;
      }
 
      return WIFI_AP_STATE.class.getEnumConstants()[tmp];
    } catch (Exception e) {
      Log.e(this.getClass().toString(), "", e);
      return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
    }
  }
 
  /**
   * Return whether Wi-Fi AP is enabled or disabled.
   * @return {@code true} if Wi-Fi AP is enabled
   * @see #getWifiApState()
   *
   * @hide Dont open yet
   */
  public boolean isWifiApEnabled() {
    return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
  }
 
  /**
   * Gets the Wi-Fi AP Configuration.
   * @return AP details in {@link WifiConfiguration}
   */
  public WifiConfiguration getWifiApConfiguration() {
    try {
      Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
      return (WifiConfiguration) method.invoke(mWifiManager);
    } catch (Exception e) {
      Log.e(this.getClass().toString(), "", e);
      return null;
    }
  }
 
  /**
   * Sets the Wi-Fi AP Configuration.
   * @return {@code true} if the operation succeeded, {@code false} otherwise
   */
  public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
    try {
      Method method = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
      return (Boolean) method.invoke(mWifiManager, wifiConfig);
    } catch (Exception e) {
      Log.e(this.getClass().toString(), "", e);
      return false;
    }
  }
 
  /**
   * Gets a list of the clients connected to the Hotspot, reachable timeout is 300
   * @param onlyReachables {@code false} if the list should contain unreachable (probably disconnected) clients, {@code true} otherwise
   * @param finishListener, Interface called when the scan method finishes
   */
  public void getClientList(boolean onlyReachables, FinishScanListener finishListner) {
    getClientList(onlyReachables, 300, finishListner );
  }
 
  /**
   * Gets a list of the clients connected to the Hotspot 
   * @param onlyReachables {@code false} if the list should contain unreachable (probably disconnected) clients, {@code true} otherwise
   * @param reachableTimeout Reachable Timout in miliseconds
   * @param finishListener, Interface called when the scan method finishes 
   */
  public void getClientList(final boolean onlyReachables, final int reachableTimeout, final FinishScanListener finishListener) {
 
 
    Runnable runnable = new Runnable() {
      public void run() {
 
        BufferedReader br = null;
        final ArrayList<ClientScanResult> result = new ArrayList<ClientScanResult>();
 
        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)) {
              // Basic sanity check
              String mac = splitted[3];
 
              if (mac.matches("..:..:..:..:..:..")) {
                boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);
 
                if (!onlyReachables || 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 a handler that can be used to post to the 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();
  }
}

License:
The Code is free and open source available under the Apache V2 License.

Fork me on GitHub

32 thoughts on “Android Wifi Hotspot Manager Class

  1. Im having some problems yo open hotspot with hidden ssid by code, is this posible? Im thinking in that solution because o couldn’t connect to a password secury wifi. Any information about this?

    Thank you very much in advance!

      • Sorry about my last post, i wrote it on my cell phone and didnt checked it after writing. Im trying to open a hotspot with hiddenSSID set to true, but i can see it from all devices. Is the atribute deprecated? I have to set something else?

        WifiManagermWifiManager = (WifiManager) this.context.getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration wifiConfig = new WifiConfiguration();
        wifiConfig.SSID = “NETWORK”;
        wifiConfig.status = WifiConfiguration.Status.ENABLED;
        wifiConfig.hiddenSSID=true;
        Method method = mWifiManager.getClass().getMethod(“setWifiApEnabled”, WifiConfiguration.class, boolean.class);
        return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);

  2. when I disconnect client, the example can’t update the clients list in the view. And I restart the app, it can’t know the client has been disconnected either, how to know client was disconnected dynamitially?

  3. Is it possible to control access to internet after creating wifi hotspot. (like disabling internet access but keeping the wifi on)

  4. Hey, great class. Do you think there is a way to view the montly per-client data usage? I’d like o have some more detailed stats than what Android provides.

    • private void configWifi(){
      wc.SSID = “\”SSIDName\””;
      wc.preSharedKey = “password”;
      wc.hiddenSSID = true;
      wc.status = WifiConfiguration.Status.ENABLED;
      wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
      wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
      wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
      wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
      wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
      wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

  5. I want to define a connection to my access point. I want receive notifications when users connected. I know that I can query arp table(/proc/net/arp) , from which I can find connected users.
    Is there any better way to do this, except viewing arp-table every n seconds?

    • Well you could start a seperate Thread that calls an event listener instance. Inside this thread you would poll. This would not solve your problem at all but hides it ;-)

  6. Hello.

    i used the above method to turn on tethering. But my AP is not found by other wifi devices. I am setting an odroid-A device as hotspot. Other wifi mobiles doesnot detect the hotspot.

    What could be the reason

  7. Hi, first of all thank you it’s very useful!
    But, do you know which broadcast intent is necessary for broadcast receivers which should listen on changes made on the device’s AP (enabling, disabling,…) ?

    thx & regards

  8. Thank, Good Information.

    if use ClientList than Use ‘Flags’ in ‘/proc/net/arp’ file.

    it can check connected or not connected~

    • Thanks for your interesting idea, could you implement it and make a pull request on github? If that’s too complicated for you, could you just send me a code example?

      Best Regards
      Nick

  9. Hi Nick, great job.
    Do you know if it is possible to change the channel also?
    By default is 6, but I want to change it. I was looking in the source and I discover one field which could be suitable for that but I didn’t get anything (no change, no error)
    I’m doing this:
    WifiConfiguration netConfig = new WifiConfiguration();
    netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

    Field wcAdhocFreq = WifiConfiguration.class.getField(“frequency”);
    wcAdhocFreq.setAccessible(true);
    wcAdhocFreq.setInt(netConfig, 2462); //2462 = center freq of channel 11

    mWifiApManager.setWifiApEnabled(netConfig, true);

    any idea? thx!

  10. Hey, I found this by Google and I must say it’s so helpful, thank you for sharing :) I’ve literally just plugged this into my app (made your example app a library in eclipse) and it works like an ace, but I’m wondering if it’s possible to get the IP address of the hotspot? Can I get that from the WifiManager object? Also, do you have any specific license you want to put this under or is it free?

  11. can you tell me why is the getWifiApConfiguration() function return null and also it does not set the WifiConfiguration options when passed in setWifiApEnabled() it just uses the default Ap options.

    • Could you tell me the android version you are using? Best case you could provide me a version of the emulator to reproduce the (potential) bug?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>