移动热点相关处理
parent
1419a28e1c
commit
5788aad1df
@ -0,0 +1,248 @@
|
|||||||
|
package com.xypower.common;
|
||||||
|
|
||||||
|
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 androidx.annotation.RequiresApi;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.android.dx.stock.ProxyBuilder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
|
||||||
|
public class HotspotManager {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
public static class OreoWifiManager {
|
||||||
|
private static final String TAG = OreoWifiManager.class.getSimpleName();
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
|
||||||
|
public OreoWifiManager(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);
|
||||||
|
Log.d(TAG, "setWifiApConfiguration - success? " + status);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error in configureHotspot");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
Log.e(TAG, "getTetheredIfaces is null");
|
||||||
|
} else {
|
||||||
|
String res[] = (String[]) method.invoke(mConnectivityManager, null);
|
||||||
|
Log.d(TAG, "getTetheredIfaces invoked");
|
||||||
|
Log.d(TAG, Arrays.toString(res));
|
||||||
|
if (res.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error in getTetheredIfaces");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
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 OnStartTetheringCallback 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()) {
|
||||||
|
Log.d(TAG, "Tether already active, returning");
|
||||||
|
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) {
|
||||||
|
Log.e(TAG, "Error in enableTethering ProxyBuilder");
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Method method = null;
|
||||||
|
try {
|
||||||
|
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
|
||||||
|
if (method == null) {
|
||||||
|
Log.e(TAG, "startTetheringMethod is null");
|
||||||
|
} else {
|
||||||
|
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
|
||||||
|
Log.d(TAG, "startTethering invoked");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error in enableTethering");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopTethering() {
|
||||||
|
try {
|
||||||
|
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
|
||||||
|
if (method == null) {
|
||||||
|
Log.e(TAG, "stopTetheringMethod is null");
|
||||||
|
} else {
|
||||||
|
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
|
||||||
|
Log.d(TAG, "stopTethering invoked");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "stopTethering error: " + e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class OnStartTetheringCallbackClass() {
|
||||||
|
try {
|
||||||
|
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
Log.e(TAG, "OnStartTetheringCallbackClass error: " + e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class OnStartTetheringCallback {
|
||||||
|
/**
|
||||||
|
* Called when tethering has been successfully started.
|
||||||
|
*/
|
||||||
|
public abstract void onTetheringStarted();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when starting tethering failed.
|
||||||
|
*/
|
||||||
|
public abstract void onTetheringFailed();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
private static void setHotspotOnPhone(Context mContext, boolean isEnable) {
|
||||||
|
|
||||||
|
OreoWifiManager mTestOreoWifiManager = null;
|
||||||
|
|
||||||
|
if (mTestOreoWifiManager ==null) {
|
||||||
|
mTestOreoWifiManager = new OreoWifiManager(mContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isEnable){
|
||||||
|
OnStartTetheringCallback callback = new OnStartTetheringCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTetheringStarted() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTetheringFailed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mTestOreoWifiManager.startTethering(callback);
|
||||||
|
}else{
|
||||||
|
mTestOreoWifiManager.stopTethering();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public static void setWiFiApEnable(Context context, boolean isEnable) {
|
||||||
|
ConnectivityManager mConnectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
if (isEnable) {
|
||||||
|
mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, false, new ConnectivityManager.OnStartTetheringCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTetheringStarted() {
|
||||||
|
Log.d(TAG, "onTetheringStarted");
|
||||||
|
// Don't fire a callback here, instead wait for the next update from wifi.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTetheringFailed() {
|
||||||
|
Log.d(TAG, "onTetheringFailed");
|
||||||
|
// TODO: Show error.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static void enableHotspot(Context context, boolean isEnable) {
|
||||||
|
// R: Adnroid 11
|
||||||
|
// O: Android 8
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// Android 11
|
||||||
|
setHotspotOnPhone(context, isEnable);
|
||||||
|
}/* else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// Android 8
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue