Comment activer / désactiver le hotspot wifi de façon programmatique dans Android 8.0 (Oreo)
je sais comment activer/désactiver le point chaud wifi en utilisant la réflexion sur android en utilisant la méthode ci-dessous.
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;
}
mais la méthode ci-dessus ne fonctionne pas Android 8.0(Oreo).
Quand j'exécute la méthode ci-dessus dans Android 8.0, je reçois la déclaration ci-dessous dans logcat.
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true
Est-il un autre moyen pour on/off hotspot sur android 8.0
3 réponses
finalement j'ai eu la solution. Android 8.0, ils ont fourni l'api publique pour activer / désactiver hotspot. WifiManager
ci-dessous est le code pour allumer le 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();
}
}
La méthode onStarted(WifiManager.LocalOnlyHotspotReservation reservation)
sera appelée si hotspot est activé.. En utilisant WifiManager.LocalOnlyHotspotReservation
référence vous appelez close()
méthode à arrêt hotspot .
Note:
Pour activer le hotspot, le Location(GPS)
doit être activé dans l'appareil. Sinon, il lancera SecurityException
je pensais que la route LocalOnlyHotspot
était le chemin, mais comme @edsappfactory.com dit dans les commentaires - il donne seulement réseau fermé, pas d'accès à internet.
dans Oreo hot-spotting/tethering déplacé à ConnectionManager
, et son annoté @SystemApi
, donc (nominalement) inaccessible.
dans le cadre de quelque chose d'autre que je faisais, j'ai fait une application et je l'ai mise sur GitHub ici . Il utilise la réflexion pour aller à la fonction et DexMaker pour générer une sous-classe de ConnectionManager.OnStartTetheringCallback
(qui est également inaccessible).
Pense que tout cela fonctionne d'accord - peu rude sur les bords, n'hésitez pas à faire mieux!
les bits de code pertinents sont dans:
j'ai perdu patience j'essaie d'obtenir mon rappel généré par DexMaker pour lancer le MyOnStartTetheringCallback
donc tout ce code est en désordre et commenté.
comme D'après la suggestion de Jon, j'ai trouvé une autre façon d'activer WifiHotSpot dans Android Oreo et au-dessus.
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;
}