Android turn On/Off WiFi HotSpot programmatically
Asked Answered
I

13

76

Is there an API to turn On/Off the WiFi HotSpot on Android programmatically?

What methods should I call to turn it On/Off?

UPDATE:There's this option to have the HotSpot enabled, and just turn On/Off the WiFi, but this is not a good solution for me.

Implant answered 18/6, 2011 at 7:39 Comment(3)
Try this: #13947107Delouse
@mxg,... how is your status right now... is it solved?Deanery
@Implant for Oreo See #45984845Stefa
J
62

Warning This method will not work beyond 5.0, it was a quite dated entry.

Use the class below to change/check the Wifi hotspot setting:

import android.content.*;
import android.net.wifi.*;
import java.lang.reflect.*;

public class ApManager {

//check whether wifi hotspot on or off
public static boolean isApOn(Context context) {
    WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);     
    try {
        Method method = wifimanager.getClass().getDeclaredMethod("isWifiApEnabled");
        method.setAccessible(true);
        return (Boolean) method.invoke(wifimanager);
    }
    catch (Throwable ignored) {}
    return false;
}

// toggle wifi hotspot on or off
public static boolean configApState(Context context) {
    WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
    WifiConfiguration wificonfiguration = null;
    try {  
        // if WiFi is on, turn it off
        if(isApOn(context)) {               
            wifimanager.setWifiEnabled(false);
        }               
        Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);                   
        method.invoke(wifimanager, wificonfiguration, !isApOn(context));
        return true;
    } 
    catch (Exception e) {
        e.printStackTrace();
    }       
    return false;
}
} // end of class

You need to add the permissions below to your AndroidMainfest:

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Use this standalone ApManager class from anywhere as follows:

ApManager.isApOn(YourActivity.this); // check Ap state :boolean
ApManager.configApState(YourActivity.this); // change Ap state :boolean

Hope this will help someone

Jungjungfrau answered 14/5, 2014 at 9:43 Comment(8)
your answer is quite long... but the owner of the question seems don't see it as an answer @AshishSahu?Deanery
It is working for me! thanks and I have to disable wifi function first before run the wifi in AP mode. Otherwise I got error: Failed to start soft AP with a running supplicantAreopagite
Thanks. I had to add the following permission to make it work on Android 6: <uses-permission android:name="android.permission.WRITE_SETTINGS" />Daredeviltry
This no longer works in Android 6+. See here: https://mcmap.net/q/270277/-android-6-0-1-couldn-39-t-enable-wifi-hotspot-programmatically. Instead of ACTION_SETTINGS, use ACTION_PICK_WIFI_NETWORKAmerigo
@Amerigo This is wrong, I just tested this on a Nexus 5X with 7.1.1, it is however necessary that you give WRITE_SETTINGS permission which requires the user to accept specifically.Unexpressive
I can't get Galaxy S9 to start hotspot programmatically! (using Pie or 10)Pelerine
Is there any method to disconnect connected device from a hotspot?Kaleykaleyard
wificonfiguration always null here thats why i get NoSuchMethodException for setWifiApEnabled... what should i do?Jacynth
D
10

Here's the complete solution if you want to implement the wifi hotspot feature programmatically in your android app.

SOLUTION FOR API < 26:

For devices < API 26. There is no public API by Android for this purpose. So, in order to work with those APIs you've to access private APIs through reflection. It is not recommended but if you've no other options left, then here's a trick.

First of all, you need to have this permission in your manifest,

  <uses-permission  
  android:name="android.permission.WRITE_SETTINGS"  
  tools:ignore="ProtectedPermissions"/>

  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Here's how you can ask it on run-time:

 private boolean showWritePermissionSettings() {    
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M  
    && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 
  if (!Settings.System.canWrite(this)) {    
    Log.v("DANG", " " + !Settings.System.canWrite(this));   
    Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); 
    intent.setData(Uri.parse("package:" + this.getPackageName()));  
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    this.startActivity(intent); 
    return false;   
  } 
}   
return true; //Permission already given 
}

You can then access the setWifiEnabled method through reflection. This returns true if the action you asked for is being process correctly i.e. enabling/disabling hotspot.

     public boolean setWifiEnabled(WifiConfiguration wifiConfig, boolean enabled) { 
 WifiManager wifiManager;
try {   
  if (enabled) { //disables wifi hotspot if it's already enabled    
    wifiManager.setWifiEnabled(false);  
  } 

   Method method = wifiManager.getClass()   
      .getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);   
  return (Boolean) method.invoke(wifiManager, wifiConfig, enabled); 
} catch (Exception e) { 
  Log.e(this.getClass().toString(), "", e); 
  return false; 
}   
}

You can also get the wificonfiguration of your hotspot through reflection. I've answered that method for this question on StackOverflow.

P.S: If you don't want to turn on hotspot programmatically, you can start this intent and open the wifi settings screen for user to turn it on manually.

SOLUTION FOR API >= 26:

Finally, android released an official API for versions >= Oreo. You can just use the public exposed API by android i.e. startLocalOnlyHotspot

It turns on a local hotspot without internet access. Which thus can be used to host a server or transfer files.

It requires Manifest.permission.CHANGE_WIFI_STATE and ACCESS_FINE_LOCATION permissions.

Here's a simple example of how you can turn on hotspot using this API.

private WifiManager wifiManager;
WifiConfiguration currentConfig;
WifiManager.LocalOnlyHotspotReservation hotspotReservation;

The method to turn on hotspot:

@RequiresApi(api = Build.VERSION_CODES.O)
public void turnOnHotspot() {

      wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

        @Override
        public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
          super.onStarted(reservation);
          hotspotReservation = reservation;
          currentConfig = hotspotReservation.getWifiConfiguration();

          Log.v("DANG", "THE PASSWORD IS: "
              + currentConfig.preSharedKey
              + " \n SSID is : "
              + currentConfig.SSID);

          hotspotDetailsDialog();

        }

        @Override
        public void onStopped() {
          super.onStopped();
          Log.v("DANG", "Local Hotspot Stopped");
        }

        @Override
        public void onFailed(int reason) {
          super.onFailed(reason);
          Log.v("DANG", "Local Hotspot failed to start");
        }
      }, new Handler());
    }
`

Here's how you can get details of the locally created hotspot

private void hotspotDetaisDialog()
{

    Log.v(TAG, context.getString(R.string.hotspot_details_message) + "\n" + context.getString(
              R.string.hotspot_ssid_label) + " " + currentConfig.SSID + "\n" + context.getString(
              R.string.hotspot_pass_label) + " " + currentConfig.preSharedKey);

}

If it throws, a security exception even after giving the required permissions then you should try enabling your location using GPS. Here's the solution.

Recently, I've developed a demo app called Spotserve. That turns on wifi hotspot for all devices with API>=15 and hosts a demo server on that hotspot. You can check that for more details. Hope this helps!

Dagger answered 6/8, 2019 at 2:27 Comment(4)
and how to connect to the local only hotspot within app. and also how to set specific ssid and passwordPleuropneumonia
is it possible off hotspot for specify device?Kaleykaleyard
The API >= 26 method worked, but I needed to initialize the wifiManager first: wifiManager = (WifiManager) this.getSystemService(this.WIFI_SERVICE);Investigation
@AdeelZafar, with the startLocalOnlyHotspot method, is there a way to configure the SSID/password?Graner
E
4

Warning This method will not work beyond 5.0, it was a quite dated entry.

You can use the following code to enable, disable and query the wifi direct state programatically.

package com.kusmezer.androidhelper.networking;

import java.lang.reflect.Method;
import com.google.common.base.Preconditions;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.util.Log;

public final class WifiApManager {
      private static final int WIFI_AP_STATE_FAILED = 4;
      private final WifiManager mWifiManager;
      private final String TAG = "Wifi Access Manager";
      private Method wifiControlMethod;
      private Method wifiApConfigurationMethod;
      private Method wifiApState;

      public WifiApManager(Context context) throws SecurityException, NoSuchMethodException {
       context = Preconditions.checkNotNull(context);
       mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
       wifiControlMethod = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class,boolean.class);
       wifiApConfigurationMethod = mWifiManager.getClass().getMethod("getWifiApConfiguration",null);
       wifiApState = mWifiManager.getClass().getMethod("getWifiApState");
      }   
      public boolean setWifiApState(WifiConfiguration config, boolean enabled) {
       config = Preconditions.checkNotNull(config);
       try {
        if (enabled) {
            mWifiManager.setWifiEnabled(!enabled);
        }
        return (Boolean) wifiControlMethod.invoke(mWifiManager, config, enabled);
       } catch (Exception e) {
        Log.e(TAG, "", e);
        return false;
       }
      }
      public WifiConfiguration getWifiApConfiguration()
      {
          try{
              return (WifiConfiguration)wifiApConfigurationMethod.invoke(mWifiManager, null);
          }
          catch(Exception e)
          {
              return null;
          }
      }
      public int getWifiApState() {
       try {
            return (Integer)wifiApState.invoke(mWifiManager);
       } catch (Exception e) {
        Log.e(TAG, "", e);
            return WIFI_AP_STATE_FAILED;
       }
      }
}
Enshroud answered 13/5, 2013 at 7:12 Comment(5)
@ldce Reflection it's not an API. Feathermore, I checked it on Nexus 5 with Lollipop and it still works.Host
@Host it works on Nexus 5 with Lollipop? Doesn't work on my AT&T S6 Lollipop 5.1.1Cann
Probably they removed it in the new releasesEnshroud
why do you post an example with third party library com.google.common.base.Preconditions;?Arraignment
It is a quite dated entry, so basically it will not work with the new versions.Enshroud
S
4

For Android 8.0, there is a new API to handle Hotspots. As far as I know, the old way using reflection doesn't work anymore. Please refer to:

Android Developers https://developer.android.com/reference/android/net/wifi/WifiManager.html#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)

void startLocalOnlyHotspot (WifiManager.LocalOnlyHotspotCallback callback, 
                Handler handler)

Request a local only hotspot that an application can use to communicate between co-located devices connected to the created WiFi hotspot. The network created by this method will not have Internet access.

Stack Overflow
How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)

onStarted(WifiManager.LocalOnlyHotspotReservation reservation) method will be called if hotspot is turned on.. Using WifiManager.LocalOnlyHotspotReservation reference you call close() method to turn off hotspot.

Stomachache answered 25/1, 2018 at 11:29 Comment(0)
O
2

This works well for me:

WifiConfiguration apConfig = null;
Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
method.invoke(wifimanager, apConfig, true);
Overvalue answered 18/2, 2014 at 9:2 Comment(2)
if that's the way you could turn on the Wifi Hotspot, then... how could you turn it off?Deanery
This is working till the Android 4.4 only. From Android 5.0 and above versions it is not working to connect to the hotspot.Agnusago
G
2

APManager - Access Point Manager

Step 1 : Add the jcenter repository to your build file
allprojects {
    repositories {
        ...
        jcenter()
    }
}
Step 2 : Add the dependency
dependencies {
    implementation 'com.vkpapps.wifimanager:APManager:1.0.0'
}
Step 3 use in your app
APManager apManager = APManager.getApManager(this);
apManager.turnOnHotspot(this, new APManager.OnSuccessListener() {

    @Override
    public void onSuccess(String ssid, String password) {
        //write your logic
    }

}, new APManager.OnFailureListener() {

    @Override
    public void onFailure(int failureCode, @Nullable Exception e) {
        //handle error like give access to location permission,write system setting permission,
        //disconnect wifi,turn off already created hotspot,enable GPS provider
        
        //or use DefaultFailureListener class to handle automatically
    }

});

check out source code https://github.com/vijaypatidar/AndroidWifiManager

Gab answered 20/11, 2020 at 13:46 Comment(3)
This creates the hotspot but didn't share the internet connectivity of the mobile data.Gretel
I love this answer <3Translator
@KrunalShah This library internally uses LocalHotspot API for Andoird 8.0+ which didn’t allow sharing internet.Gab
V
1

Your best bet will be looking at the WifiManager class. Specifically the setWifiEnabled(bool) function.

See the documentation at: http://developer.android.com/reference/android/net/wifi/WifiManager.html#setWifiEnabled(boolean)

A tutorial on how to use it (including what permissions you need) can be found here: https://web.archive.org/web/20210228070142/http://www.tutorialforandroid.com/2009/10/turn-off-turn-on-wifi-in-android-using.html

Valvule answered 18/6, 2011 at 7:43 Comment(3)
Is it possible without turning On/Off the WiFi?Implant
Possibly, still using the WifiManager class. See this SO question: #3023726 (I think that's your best bet.)Valvule
he talks about WiFi hotspot, not just WiFiArraignment
C
1

I have publish unofficial api's for same, it's contains more than just hotspot turn on/off. link

For API's DOC - link.

Choker answered 16/12, 2014 at 8:31 Comment(1)
Note that the provided API is for the device acting as a client connecting to an AP, while the OP was looking for ways to control the built-in AP.Wilone
S
0

**For Oreo & PIE ** I found below way through this

private WifiManager.LocalOnlyHotspotReservation mReservation;
private boolean isHotspotEnabled = false;
private final int REQUEST_ENABLE_LOCATION_SYSTEM_SETTINGS = 101;

private boolean isLocationPermissionEnable() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION}, 2);
        return false;
    }
    return true;
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
    if (!isLocationPermissionEnable()) {
        return;
    }
    WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

    if (manager != null) {
        // Don't start when it started (existed)
        manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

            @Override
            public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
                super.onStarted(reservation);
                //Log.d(TAG, "Wifi Hotspot is on now");
                mReservation = reservation;
                isHotspotEnabled = true;
            }

            @Override
            public void onStopped() {
                super.onStopped();
                //Log.d(TAG, "onStopped: ");
                isHotspotEnabled = false;
            }

            @Override
            public void onFailed(int reason) {
                super.onFailed(reason);
                //Log.d(TAG, "onFailed: ");
                isHotspotEnabled = false;
            }
        }, new Handler());
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOffHotspot() {
    if (!isLocationPermissionEnable()) {
        return;
    }
    if (mReservation != null) {
        mReservation.close();
        isHotspotEnabled = false;
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void toggleHotspot() {
    if (!isHotspotEnabled) {
        turnOnHotspot();
    } else {
        turnOffHotspot();
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void enableLocationSettings() {
    LocationRequest mLocationRequest = new LocationRequest();
    /*mLocationRequest.setInterval(10);
    mLocationRequest.setSmallestDisplacement(10);
    mLocationRequest.setFastestInterval(10);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);*/
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(mLocationRequest)
            .setAlwaysShow(false); // Show dialog

    Task<LocationSettingsResponse> task= LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());

    task.addOnCompleteListener(task1 -> {
        try {
            LocationSettingsResponse response = task1.getResult(ApiException.class);
            // All location settings are satisfied. The client can initialize location
            // requests here.
            toggleHotspot();

        } catch (ApiException exception) {
            switch (exception.getStatusCode()) {
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the
                    // user a dialog.
                    try {
                        // Cast to a resolvable exception.
                        ResolvableApiException resolvable = (ResolvableApiException) exception;
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        resolvable.startResolutionForResult(HotspotActivity.this, REQUEST_ENABLE_LOCATION_SYSTEM_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    } catch (ClassCastException e) {
                        // Ignore, should be an impossible error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way to fix the
                    // settings so we won't show the dialog.
                    break;
            }
        }
    });
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    switch (requestCode) {
        case REQUEST_ENABLE_LOCATION_SYSTEM_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // All required changes were successfully made
                    toggleHotspot();
                    Toast.makeText(HotspotActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
                    break;
                case Activity.RESULT_CANCELED:
                    // The user was asked to change settings, but chose not to
                    Toast.makeText(HotspotActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
            break;
    }
}

UseAge

btnHotspot.setOnClickListenr(view -> {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // Step 1: Enable the location settings use Google Location Service
        // Step 2: https://mcmap.net/q/166228/-how-to-show-enable-location-dialog-like-google-maps/50796199#50796199
        // Step 3: If OK then check the location permission and enable hotspot
        // Step 4: https://mcmap.net/q/270282/-how-to-turn-off-wifi-hotspot-programmatically-in-android-8-0-oreo-setwifiapenabled-is-not-support-this-version-anymore
        enableLocationSettings();
        return;
    }
}

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

implementation 'com.google.android.gms:play-services-location:15.0.1'
Stefa answered 6/11, 2018 at 6:52 Comment(0)
H
0

We can programmatically turn on and off

setWifiApDisable.invoke(connectivityManager, TETHERING_WIFI);//Have to disable to enable
setwifiApEnabled.invoke(connectivityManager, TETHERING_WIFI, false, mSystemCallback,null);

Using callback class, to programmatically turn on hotspot in pie(9.0) u need to turn off programmatically and the switch on.

Hobbie answered 8/4, 2019 at 9:23 Comment(1)
Provide some more information on the code you added here.Strength
T
0

You can use the console and service for that option.

I think with this you can solve that. I made a test directly in console and enable hotspot

I found this in this article Is it possible to USB tether an android device using adb through the terminal?

And after read the interface we can use the same 24 but needs more parameters

service call connectivity 24 i32 0 i32 1 i32 0 s16 random

Tagliatelle answered 11/7, 2019 at 15:17 Comment(0)
F
0

You can use command line with root access

To turn on hotspot.

adb shell su -c service call connectivity 24 i32 0 i32 0 i32 0 s16 random

To turn off hotspot

adb shell su -c service call connectivity 25 i32 0 i32 0 i32 0 s16 random
Flashy answered 17/3, 2022 at 9:3 Comment(1)
can u explain what "24 i32 0 i32 0 i32 0" is mean?Mcnulty
S
-3
WifiManager wifiManager = (WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(status);

where status may be true or false

add permission manifest: <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

Solifluction answered 17/8, 2012 at 15:55 Comment(1)
That only turns wifi on/off, not the HotSpot.Averse

© 2022 - 2024 — McMap. All rights reserved.