Ich weiß, wie man den WLAN-Hotspot mit Reflexion in Android mit der untenstehenden Methode ein/ausschaltet.
private static boolean changeWifiHotspotState(Context context,boolean enable) {
try {
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
Boolean.TYPE);
method.setAccessible(true);
WifiConfiguration configuration = enable ? getWifiApConfiguration(manager) : null;
boolean isSuccess = (Boolean) method.invoke(manager, configuration, enable);
return isSuccess;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
Aber die obige Methode funktioniert nicht mit Android 8.0 (Oreo).
Wenn ich die obige Methode in Android 8.0 ausführen, erhalte ich in logcat die folgende Aussage.
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true
Gibt es eine andere Möglichkeit, Hotspot unter Android 8.0 ein- oder auszuschalten?
Endlich bekam ich die Lösung ... __ Android 8.0, sie lieferte ein öffentliches API, um Hotspot ein-/auszuschalten. WifiManager
Unten ist der Code zum Aktivieren von 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();
}
}
Die onStarted(WifiManager.LocalOnlyHotspotReservation reservation)
-Methode wird aufgerufen, wenn Hotspot aktiviert ist. Mit WifiManager.LocalOnlyHotspotReservation
reference rufen Sie die close()
-Methode auf, um hotspot auszuschalten.
Hinweis: Um den Hotspot zu aktivieren, muss die Location(GPS)
im Gerät aktiviert sein. Andernfalls wird SecurityException
ausgegeben.
Ich dachte, die LocalOnlyHotspot
-Route wäre der Weg zu, aber wie @ edsappfactory.com in den Kommentaren sagte - es gibt nur ein geschlossenes Netzwerk, keinen Internetzugang.
In Oreo wurde Hot-Spotting/Tethering nach ConnectionManager
verschoben, und sein kommentierter @SystemApi
ist (nominell) nicht zugänglich.
Als Teil von etwas anderem machte ich eine App und legte sie auf github hier . Es verwendet Reflektion, um an die Funktion zu gelangen und DexMaker , um eine Unterklasse von ConnectionManager.OnStartTetheringCallback
(die auch nicht zugänglich ist) zu generieren.
Ich finde, es funktioniert alles in Ordnung - etwas rau an den Rändern.
Relevante Codebits sind in:
Ich verlor die Geduld, als ich versuchte, meinen von DexMaker generierten Callback dazu zu bringen, die MyOnStartTetheringCallback
auszulösen, sodass der gesamte Code in Unordnung geraten ist und auskommentiert wird.
Laut Jon-Vorschlag erhielt ich eine weitere Möglichkeit, Wifi HotSpot in Android Oreo und höher zu aktivieren.
public boolean enableTetheringNew(MyTetheringCallback callback) {
File outputDir = mContext.getCodeCacheDir();
try {
proxy = ProxyBuilder.forClass(classOnStartTetheringCallback())
.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 (IOException e) {
e.printStackTrace();
}
ConnectivityManager manager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(ConnectivityManager.class);
Method method = null;
try {
method = manager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, classOnStartTetheringCallback(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(manager, TETHERING_WIFI, false, proxy, null);
}
return true;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
private Class classOnStartTetheringCallback() {
try {
return Class.forName("Android.net.ConnectivityManager$OnStartTetheringCallback");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}