forked from jens/Automation
205 lines
7.3 KiB
Java
205 lines
7.3 KiB
Java
package com.jens.automation2.actions.wifi_router;
|
|
|
|
/*
|
|
Class taken from here:
|
|
https://github.com/aegis1980/WifiHotSpot
|
|
*/
|
|
|
|
import android.content.Context;
|
|
import android.net.ConnectivityManager;
|
|
import android.net.wifi.WifiConfiguration;
|
|
import android.net.wifi.WifiManager;
|
|
import android.os.Build;
|
|
import android.os.Handler;
|
|
import android.util.Log;
|
|
import androidx.annotation.RequiresApi;
|
|
|
|
import com.android.dx.stock.ProxyBuilder;
|
|
import com.jens.automation2.Miscellaneous;
|
|
|
|
import java.io.File;
|
|
import java.lang.reflect.InvocationHandler;
|
|
import java.lang.reflect.Method;
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* Created by jonro on 19/03/2018.
|
|
*/
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
|
public class MyOreoWifiManager
|
|
{
|
|
private static final String TAG = MyOreoWifiManager.class.getSimpleName();
|
|
|
|
private Context mContext;
|
|
private WifiManager mWifiManager;
|
|
private ConnectivityManager mConnectivityManager;
|
|
|
|
public MyOreoWifiManager(Context c)
|
|
{
|
|
mContext = c;
|
|
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
|
|
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(ConnectivityManager.class);
|
|
}
|
|
|
|
/**
|
|
* This sets the Wifi SSID and password
|
|
* Call this before {@code startTethering} if app is a system/privileged app
|
|
* Requires: android.permission.TETHER_PRIVILEGED which is only granted to system apps
|
|
*/
|
|
public void configureHotspot(String name, String password)
|
|
{
|
|
WifiConfiguration apConfig = new WifiConfiguration();
|
|
apConfig.SSID = name;
|
|
apConfig.preSharedKey = password;
|
|
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
|
|
try
|
|
{
|
|
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
|
|
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
|
|
Miscellaneous.logEvent("i", "configureHotspot()", "setWifiApConfiguration - success? " + status, 2);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Miscellaneous.logEvent("e", "configureHotspot()", "Error in configureHotspot: " + Log.getStackTraceString(e), 2);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks where tethering is on.
|
|
* This is determined by the getTetheredIfaces() method,
|
|
* that will return an empty array if not devices are tethered
|
|
*
|
|
* @return true if a tethered device is found, false if not found
|
|
*/
|
|
public boolean isTetherActive()
|
|
{
|
|
try
|
|
{
|
|
Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
|
|
if (method == null)
|
|
{
|
|
Miscellaneous.logEvent("i", "getTetheredIfaces()", "getTetheredIfaces is null", 2);
|
|
}
|
|
else
|
|
{
|
|
String res[] = (String []) method.invoke(mConnectivityManager, null);
|
|
Miscellaneous.logEvent("i", "isTetherActive()", "getTetheredIfaces invoked", 5);
|
|
Miscellaneous.logEvent("i", "isTetherActive()", Arrays.toString(res), 4);
|
|
|
|
if (res.length > 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Miscellaneous.logEvent("e", "isTetherActive()", "Error in getTetheredIfaces: " + Log.getStackTraceString(e), 2);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
|
|
* Does not require app to have system/privileged access
|
|
* Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
|
|
*/
|
|
public boolean startTethering(final MyOnStartTetheringCallback callback)
|
|
{
|
|
// On Pie if we try to start tethering while it is already on, it will
|
|
// be disabled. This is needed when startTethering() is called programmatically.
|
|
if (isTetherActive())
|
|
{
|
|
Miscellaneous.logEvent("i", "startTethering()", "Tether already active, returning", 2);
|
|
return false;
|
|
}
|
|
|
|
File outputDir = mContext.getCodeCacheDir();
|
|
Object proxy;
|
|
try
|
|
{
|
|
proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass())
|
|
.dexCache(outputDir).handler(new InvocationHandler()
|
|
{
|
|
@Override
|
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
|
|
{
|
|
switch (method.getName())
|
|
{
|
|
case "onTetheringStarted":
|
|
callback.onTetheringStarted();
|
|
break;
|
|
case "onTetheringFailed":
|
|
callback.onTetheringFailed();
|
|
break;
|
|
default:
|
|
ProxyBuilder.callSuper(proxy, method, args);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
}).build();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Miscellaneous.logEvent("e", "startTethering()", "Error in enableTethering ProxyBuilder", 2);
|
|
return false;
|
|
}
|
|
|
|
Method method = null;
|
|
try
|
|
{
|
|
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
|
|
if (method == null)
|
|
{
|
|
Miscellaneous.logEvent("w", "startTethering()", "startTetheringMethod is null", 2);
|
|
}
|
|
else
|
|
{
|
|
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
|
|
Miscellaneous.logEvent("i", "startTethering()", "startTethering invoked", 5);
|
|
}
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Miscellaneous.logEvent("w", "startTethering()", "Error in enableTethering: " + Log.getStackTraceString(e), 2);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void stopTethering()
|
|
{
|
|
try
|
|
{
|
|
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
|
|
if (method == null)
|
|
{
|
|
Miscellaneous.logEvent("w", "stopTethering", "stopTetheringMethod is null", 2);
|
|
}
|
|
else
|
|
{
|
|
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
|
|
Miscellaneous.logEvent("i", "stopTethering", "stopTethering invoked", 5);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Miscellaneous.logEvent("e", "stopTethering", "stopTethering error: " + Log.getStackTraceString(e), 1);
|
|
}
|
|
}
|
|
|
|
private Class OnStartTetheringCallbackClass()
|
|
{
|
|
try
|
|
{
|
|
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
|
|
}
|
|
catch (ClassNotFoundException e)
|
|
{
|
|
Miscellaneous.logEvent("e", "OnStartTetheringCallbackClass()", "OnStartTetheringCallbackClass error: " + Log.getStackTraceString(e), 1);
|
|
}
|
|
return null;
|
|
}
|
|
} |