android android-wifi hotspot android-8.0-oreo

Cómo activar/desactivar el punto de acceso wifi mediante programación en Android 8.0(Oreo)



android-wifi hotspot (3)

Sé cómo activar / desactivar el punto de acceso wifi usando la reflexión en Android usando el método a continuación.

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; }

Pero el método anterior no funciona con Android 8.0 (Oreo).

Cuando ejecuto el método anterior en Android 8.0, obtengo la siguiente declaración en logcat.

com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true

¿Hay alguna otra forma de activar / desactivar el punto de acceso en Android 8.0


Finalmente obtuve la solución. Android 8.0, proporcionaron una API pública para activar / desactivar el punto de acceso. WifiManager

A continuación se muestra el código para activar el punto de acceso

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(); } }

onStarted(WifiManager.LocalOnlyHotspotReservation reservation) método onStarted(WifiManager.LocalOnlyHotspotReservation reservation) si la zona activa está activada. Usando la referencia WifiManager.LocalOnlyHotspotReservation se llama al método close() para desactivar la zona activa .

Nota: Para activar el punto de acceso, la Location(GPS) debe estar habilitada en el dispositivo. De lo contrario, arrojará SecurityException


Pensé que la ruta LocalOnlyHotspot era el camino a seguir, pero como dijo @ edsappfactory.com en los comentarios, solo ofrece una red cerrada, sin acceso a Internet.

En Oreo, el hot-spotting / tethering se movió a ConnectionManager y su @SystemApi anotado, por lo tanto (nominalmente) inaccesible.

Como parte de algo más que estaba haciendo, hice una aplicación y la puse en Github aquí . Utiliza la reflexión para llegar a la función y DexMaker para generar una subclase de ConnectionManager.OnStartTetheringCallback (que también es inaccesible).

Piensa que todo funciona bien, un poco áspero en los bordes, ¡así que no dudes en mejorar!

Los bits de código relevantes están en:

Perdí la paciencia al intentar que mi devolución de llamada generada por MyOnStartTetheringCallback para que todo ese código esté en desorden y MyOnStartTetheringCallback .


Según la sugerencia de Jon, obtuve otra forma de habilitar WifiHotSpot en Android Oreo y superior.

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; }