Je sais comment activer/désactiver le point d'accès Wi-Fi à l'aide de la réflexion dans Android à l'aide de 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 avec Android 8.0 (Oreo).
Lorsque j'exécute la méthode ci-dessus dans Android 8.0, la déclaration ci-dessous apparaît dans logcat.
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true
Existe-t-il un autre moyen d'activer/de désactiver le point d'accès sur Android 8.0?
Enfin, j’ai eu la solution . Android 8.0, ils ont fourni l’API publique pour activer/désactiver le hotspot. WifiManager
Voici le code pour activer 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 le hotspot est activé. À l'aide de la référence WifiManager.LocalOnlyHotspotReservation
, vous appelez la méthode close()
pour désactiver le hotspot.
Remarque: Pour activer le point d'accès, le Location(GPS)
doit être activé sur le périphérique. Sinon, il lancera SecurityException
Je pensais que la route LocalOnlyHotspot
était la voie à suivre, mais comme @ edsappfactory.com l’a dit dans ses commentaires, il ne donne qu’un réseau fermé, pas d’accès à Internet.
Dans Oreo, le repérage à chaud/le partage de connexion est passé à ConnectionManager
, et son @SystemApi
annoté, donc (nominalement) inaccessible.
Dans le cadre de quelque chose que je faisais, j'ai créé une application et je l'ai mise sur github ici . Il utilise la réflexion pour accéder à la fonction et DexMaker pour générer une sous-classe de ConnectionManager.OnStartTetheringCallback
(également inaccessible).
Pensez que tout fonctionne bien - un peu rude sur les bords, alors n'hésitez pas à faire mieux!
Les bits de code pertinents sont dans:
J'ai perdu patience en essayant d'obtenir mon rappel généré par DexMaker pour déclencher le MyOnStartTetheringCallback
afin que tout ce code soit en désordre et mis en commentaire.
Selon la suggestion de Jon, j'ai eu un autre moyen d'activer le HotSpot Wifi 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;
}