How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)

前端 未结 3 2057
梦毁少年i
梦毁少年i 2020-11-27 05:38

I know how to turn on/off wifi hot spot using reflection in android using below method.

private static boolean changeWifiHotspotState(Context context,boolean         


        
相关标签:
3条回答
  • 2020-11-27 06:18

    As per Jon suggestion, I got another way to enable WifiHotSpot in Android Oreo and above.

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 06:33

    I thought the LocalOnlyHotspot route was the way to, but as @edsappfactory.com said in the comments - it only gives closed network, no internet access.

    In Oreo hot-spotting/tethering moved to ConnectionManager, and its annotated @SystemApi, so (nominally) inaccessible.

    As part of something else I was doing, I made an app and put it on github here. It uses reflection to get at the function and DexMaker to generate a subclass of ConnectionManager.OnStartTetheringCallback (which is also inaccessible).

    Think it all works okay - bit rough around the edges, so please feel free to make better!

    Relevant bits of code are in:

    • MyOreoWifiManager and;
    • CallbackMaker

    I lost patience trying to get my DexMaker-generated callback to fire the MyOnStartTetheringCallback so all that code is in disarray and commented out.

    0 讨论(0)
  • 2020-11-27 06:41

    Finally I got the solution. Android 8.0, they provided public api to turn on/off hotspot. WifiManager

    Below is the code to turn on 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();
        }
    }
    

    onStarted(WifiManager.LocalOnlyHotspotReservation reservation) method will be called if hotspot is turned on.. Using WifiManager.LocalOnlyHotspotReservation reference you call close() method to turn off hotspot.

    Note: To turn on hotspot, the Location(GPS) should be enabled in the device. Otherwise, it will throw SecurityException

    0 讨论(0)
提交回复
热议问题