Android 8.0 打开wifi热点

发布于 2018-11-27  240 次阅读


在 android8.0之前,Android热点方面的开发基本上都是依靠java的反射机制来完成的。
但是8.0之后,谷狗对反射系统api作了限制,之前的方法也就失效了。
下面是我在8.0或者更高的系统的踩坑记录

源码见我的工具包:KosmosUtils,欢迎issues


0.事前准备

系统的定位服务一定要保证是开启状态

/**
 * @return GPS是否打开
 */
public static boolean checkGPSIsOpen(Context context) {
    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    return locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
}

/**
 * 跳转GPS设置界面
 */
public static void openGPSSettings(Activity activity) {
   UDialog.getInstance(activity, false, false)
       .showNoticeWithOnebtn("Please open the location service",
           "To Open", (result, dia) -> {
               Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
               activity.startActivityForResult(intent, 5);
               dia.dismiss();
           });
}

1.先判断系统版本

Build.VERSION.SDK_INT >= Build.VERSION_CODES.O

2.高于8.0

系统提供了相应的api

2.1.打开热点

 getWifiMgr().startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
            @Override
            public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
                mReservation = reservation;
                sid = reservation.getWifiConfiguration().SSID;
                pwd = reservation.getWifiConfiguration().preSharedKey;
                callbak.onConnected("", sid, pwd);
            }

            @Override
            public void onStopped() {
                mReservation = null;
            }

            @Override
            public void onFailed(int reason) {
                callbak.onConnected("wifi ap is failed to open", null, null);
            }
        }, new Handler());

2.2.关闭热点

这里就比较坑了,在2.1中,热点打开后会返回一个WifiManager.LocalOnlyHotspotReservation
而关闭,则是通过这货来操作,有一定几率失败。
而且:如果是用户手动打开的热点,LocalOnlyHotspotReservation自然为空,我们也就无能为力了

if (mReservation != null) {
    mReservation.close();
    mReservation = null;
}

3.如果系统低于8.0

就可以用以前反射的方式来搞了

/**
 * 低于Android8.0 开启热点
 */
private void openApBelow8(Callbak callbak) {
    if (getWifiMgr().isWifiEnabled()) {
        //如果wifi处于打开状态,则关闭wifi,
        getWifiMgr().setWifiEnabled(false);
    }
    if (isApOpen()) {
        sid = getApSSID();
        pwd = getApPassword();
        if (!UText.isEmpty(sid) && !UText.isEmpty(pwd)) {
            callbak.onConnected("", sid, pwd);
            return;
        }
    }
    WifiConfiguration config = new WifiConfiguration();
    config.SSID = "Scan-Wifi";
    config.preSharedKey = "Scan-Wifi@233";
    config.hiddenSSID = false;//是否隐藏网络
    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);//开放系统认证
    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    config.status = WifiConfiguration.Status.ENABLED;
    try {
        Method method = getWifiMgr().getClass().getMethod("setWifiApEnabled",
            WifiConfiguration.class, Boolean.TYPE);
        Boolean result = (Boolean) method.invoke(getWifiMgr(), config, true);
        if (UText.isBoolean(result)) {
            sid = "Scan-Wifi";
            pwd = "Scan-Wifi@233";
            callbak.onConnected("", sid, pwd);
        } else {
            callbak.onConnected("wifi ap is failed to open", null, null);
        }
    } catch (Exception e) {
        callbak.onConnected("wifi ap is failed to open", null, null);
    }
}

3.1.关闭的方式

Method method = getWifiMgr().getClass().getMethod("setWifiApEnabled",
                WifiConfiguration.class, boolean.class);
method.invoke(getWifiMgr(), null, false);

赤夜染尽 千樱散落 零时夜雨 无茵之音