How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)
Finally I got the solution.
Android 8.0, they provided public api to turn on/off hotspot. WifiManager
Below is the code to turn on hotspot
private WifiManager.LocalOnlyHotspotReservation mReservation;
@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
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;
}
@Override
public void onStopped() {
super.onStopped();
Log.d(TAG, "onStopped: ");
}
@Override
public void onFailed(int reason) {
super.onFailed(reason);
Log.d(TAG, "onFailed: ");
}
}, new Handler());
}
private void turnOffHotspot() {
if (mReservation != null) {
mReservation.close();
}
}
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.
Note:
To turn on hotspot, the Location(GPS)
should be enabled in the device. Otherwise, it will throw SecurityException
Turn on/off WiFi hotspot programmatically
Theses methods works only for android 5.0 and less !
The EASY way :
Try instantiating the WifiConfiguration
first :
AndroidJavaObject wifiConfiguration = new AndroidJavaClass("android.net.wifi.WifiConfiguration");
Now you can call methods and set/get fields within this object :
// to set SSID
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
After settings all of the required fields just call your setWifiApEnabled
method :
wifiManager.Call<bool>("setWifiApEnabled", wifiConfiguration, enabled);
Maybe you will have to set more fields than these two but to confirm that you should check the source and ensure what setWifiApEnabled
method does internaly.
The HARD way :
( using reflection code )
Step 6 does not work for android 5.0+ !
Using reflection with AndroidJavaObject
can be a bit tricky because you have to remember to dispose every object.
So from the beginning :
// android code for that should look like :
// wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
// but in Unity C# you have to split this into few chunks:
// 1. Get calling class :
using ( AndroidJavaObject classObj = wifiManager.Call<AndroidJavaObject>("getClass") )
{
// classObj should contains your class object
// 2. call get WifiConfiguration class details :
using ( AndroidJavaObject wifiConfiguration = new AndroidJavaObject("setWifiApEnabled") )
{
// 3. Fill that object :
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
// 4. Get WifiConfiguration class definition
using (AndroidJavaObject wifiCfgClass = wifiConfiguration.Call<AndroidJavaObject>("getClass") )
{
// 5. Get boolean definition
using ( AndroidJavaObject booleanObj = new AndroidJavaObject("java.lang.Boolean") )
{
using ( AndroidJavaObject booleanClass = booleanObj.Call<AndroidJavaObject>("getClass") )
// 6. Get method definition
using ( AndroidJavaObject methodObj = classObj.Call<AndroidJavaObject>("getMethod", "setWifiApEnabled", wifiCfgClass , booleanClass))
{
// 7. Call that method :)
methodObj.Call("invoke", wifiManager, wifiConfiguration, enabled);
}
}
}
}
}
WifiConfiguration :
I was trying to find out why the above code might not work but for me it was working okay ( tested on some virtual machines and Samsung Galaxy S5 Neo ).
What may be the case ( which I found out at almost midnight ) is a passphrase.
According to this wikipedia article in the section about WPA-PSK
Also referred to as WPA-PSK (pre-shared key) mode, this is designed for home and small office networks and doesn't require an authentication server.[9] Each wireless network device encrypts the network traffic using a 256 bit key. This key may be entered either as a string of 64 hexadecimal digits, or as a passphrase of 8 to 63 printable ASCII characters.[10] If ASCII characters are used, the 256 bit key is calculated by applying the PBKDF2 key derivation function to the passphrase, using the SSID as the salt and 4096 iterations of HMAC-SHA1.[11] WPA-Personal mode is available with both WPA and WPA2.)
My suggestion would be to use the same passphrase as in the article linked above to make sure it's valid.
Also another thing to note is the SSID part which has a short but good description here on wikipedia.
A common, albeit incorrect assumption, is that an SSID is a string of human-readable characters (such as ASCII), terminated by a NUL character (as in a C-string). SSIDs must be treated and handled as what they are, a sequence of 0–32 octets, some of which may not be human-readable
From what I've checked you do not need to null-terminate your string within Java or C# because it will be handled by native code but still you should not exceed 31 characters ( 32 will be the null character ).
I checked this with :
SSID:MeHotSpot
WPA-PSK:5260305714217573
How to create wifihotspot in Oreo programmatically?
Oreo doesnot support to create hotspot programmatically with no password. It always creates hotspot with unique ssid and key generated randomly.
WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiManager.LocalOnlyHotspotReservation mReservation;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
assert manager != null;
manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
@SuppressLint("SetTextI18n")
@Override
public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
super.onStarted(reservation);
Timber.d("Wifi Hotspot is on now , reservation is : %s", reservation.toString());
mReservation = reservation;
key = mReservation.getWifiConfiguration().preSharedKey;
ussid = mReservation.getWifiConfiguration().SSID;
}
@Override
public void onStopped() {
super.onStopped();
Timber.d("onStopped: ");
}
@Override
public void onFailed(int reason) {
super.onFailed(reason);
Timber.d("onFailed: ");
}
}, new Handler());
}
Related Topics
"Unable to Locate Adb" Using Android Studio
Access the Http Response Headers in a Webview
Android ==> Memory Analysing ==> Eclipse Memory Analyzer
Android - File Provider - Permission Denial
Android M Permissions:Confused on the Usage of Shouldshowrequestpermissionrationale() Function
Android Adb Device Offline, Can't Issue Commands
How to Get All Android Contacts But Without Those Which Are on Sim
How to Set Internet Options for Android Emulator
Asynctask and Looper.Prepare() Error
Error Java.Lang.Classnotfoundexception: Com.Google.Android.Gms.Maps.Mapfragment in Google Map V2
Some Androids Apps Won't Connect Through Fiddler
Understanding Command Through Adb Shell and Through Code - Android
How to Programmatically Add Buttons into Layout One by One in Several Lines
Execution Failed for Task 'App:Mergedebugresources' Crunching Cruncher....Png Failed
Getting Latitude and Longitude in 30 Seconds
Keyboard Showed Messed Up Elements' Position
How to Use the Firebase Server Timestamp to Generate Date Created