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

8
demandé sur Cœur 2017-08-31 17:48:09

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

9
répondu Chandrakanth 2018-03-28 11:52:27

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é.

9
répondu Jon 2018-07-20 09:58:47

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;
}
1
répondu Vishal Sharma 2018-09-11 08:36:44