Android Wifi热点通信,及Android7.0上修改手机连接wifi方法,和其他大神提供的方法稍作修改

Android Wifi热点通信和蓝牙通信类似,一般都是物联网中应用很多的技术,通信起来比较简单,

首先封装一个wfif 工具类用来切换手机连接的wifi ,与设备在同一局域网下

public class WifiUtil {

    private WifiManager mWifiManager;
    private Context mContext;
    private final String TAG = "===WifiUtil===";

    public WifiUtil(Context context){
        this.mContext=context;
        mWifiManager=(WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    }


    /**
     * 创建热点
     * @param mSSID 热点名称
     * @param mPasswd 热点密码
     * @param isOpen 是否是开放热点
     */
    public void startWifiAp(String mSSID,String mPasswd,boolean isOpen){
        Method method1=null;
        try {
            method1=mWifiManager.getClass().getMethod("setWifiApEnabled",
                    WifiConfiguration.class,boolean.class);
            WifiConfiguration netConfig=new WifiConfiguration();

            netConfig.SSID=mSSID;
            netConfig.preSharedKey=mPasswd;
            netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            if (isOpen) {
                netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            }else {
                netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            }
            netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            method1.invoke(mWifiManager,netConfig,true);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**获取热点名**/
    public String getApSSID() {
        try {
            Method localMethod = this.mWifiManager.getClass().getDeclaredMethod("getWifiApConfiguration", new Class[0]);
            if (localMethod == null) return null;
            Object localObject1 = localMethod.invoke(this.mWifiManager,new Object[0]);
            if (localObject1 == null) return null;
            WifiConfiguration localWifiConfiguration = (WifiConfiguration) localObject1;
            if (localWifiConfiguration.SSID != null) return localWifiConfiguration.SSID;
            Field localField1 = WifiConfiguration.class .getDeclaredField("mWifiApProfile");
            if (localField1 == null) return null;
            localField1.setAccessible(true);
            Object localObject2 = localField1.get(localWifiConfiguration);
            localField1.setAccessible(false);
            if (localObject2 == null)  return null;
            Field localField2 = localObject2.getClass().getDeclaredField("SSID");
            localField2.setAccessible(true);
            Object localObject3 = localField2.get(localObject2);
            if (localObject3 == null) return null;
            localField2.setAccessible(false);
            String str = (String) localObject3;
            return str;
        } catch (Exception localException) {
        }
        return null;
    }


    /**
     * 检查是否开启Wifi热点
     * @return
     */
    public boolean isWifiApEnabled(){
        try {
            Method method=mWifiManager.getClass().getMethod("isWifiApEnabled");
            method.setAccessible(true);
            return (boolean) method.invoke(mWifiManager);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 关闭热点
     */
    public void closeWifiAp(){
        WifiManager wifiManager= (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        if (isWifiApEnabled()){
            try {
                Method method=wifiManager.getClass().getMethod("getWifiApConfiguration");
                method.setAccessible(true);
                WifiConfiguration config= (WifiConfiguration) method.invoke(wifiManager);
                Method method2=wifiManager.getClass().getMethod("setWifiApEnabled",WifiConfiguration.class,boolean.class);
                method2.invoke(wifiManager,config,false);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 开热点手机获得其他连接手机IP的方法
     * @return 其他手机IP 数组列表
     */
    public ArrayList getConnectedIP(){
        ArrayList connectedIp=new ArrayList();
        try {
            BufferedReader br=new BufferedReader(new FileReader(
                    "/proc/net/arp"));
            String line;
            while ((line=br.readLine())!=null){
                String[] splitted=line.split(" +");
                if (splitted !=null && splitted.length>=4){
                    String ip=splitted[0];
                    if (!ip.equalsIgnoreCase("ip")){
                        connectedIp.add(ip);
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return connectedIp;
    }
    // 定义几种加密方式,一种是WEP,一种是WPA,还有没有密码的情况
    public enum WifiCipherType {
        WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
    }

    // 打开wifi功能
    private boolean OpenWifi() {
        boolean bRet = true;
        if (!mWifiManager.isWifiEnabled()) {
            bRet = mWifiManager.setWifiEnabled(true);
        }
        return bRet;
    }


    // 提供一个外部接口,传入要连接的无线网
    public boolean Connect(String SSID, String Password, WifiCipherType Type) {
        if (!this.OpenWifi()) {
            return false;
        }
        // 开启wifi功能需要一段时间(我在手机上测试一般需要1-3秒左右),所以要等到wifi
        // 状态变成WIFI_STATE_ENABLED的时候才能执行下面的语句
        while (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
            try {
                // 为了避免程序一直while循环,让它睡个100毫秒在检测……
                Thread.currentThread();
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }

        WifiConfiguration wifiConfig = CreateWifiInfo(SSID, Password, Type);
        //
        if (wifiConfig == null) {
            Log.e(TAG,"====wifiConfig == null====");
            return false;
        }

        WifiConfiguration tempConfig = this.IsExsits(SSID);
        if (tempConfig != null) {
            mWifiManager.removeNetwork(tempConfig.networkId);
        }
        int netID = mWifiManager.addNetwork(wifiConfig);
        boolean bRet = mWifiManager.enableNetwork(netID, true);
        return bRet;
    }

    // 查看以前是否也配置过这个网络
    private WifiConfiguration IsExsits(String SSID) {
        List existingConfigs = mWifiManager.getConfiguredNetworks();
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                return existingConfig;
            }
        }
        return null;
    }

    /**
     * 配置连接
     * @param SSID
     * @param Password
     * @param Type
     * @return
     */
    private WifiConfiguration CreateWifiInfo(String SSID, String Password, WifiCipherType Type) {
//        WifiConfiguration config = new WifiConfiguration();
//        config.allowedAuthAlgorithms.clear();
//        config.allowedGroupCiphers.clear();
//        config.allowedKeyManagement.clear();
//        config.allowedPairwiseCiphers.clear();
//        config.allowedProtocols.clear();
//        config.SSID = "\"" + SSID + "\"";
////        config.SSID = SSID;
//        if (Type == WifiCipherType.WIFICIPHER_NOPASS) {
//            config.wepKeys[0] = "";
//            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//            config.wepTxKeyIndex = 0;
//        }
//        if (Type == WifiCipherType.WIFICIPHER_WEP) {
//            //   config.preSharedKey = "\"" + Password + "\"";
//            config.hiddenSSID = true;
//            config.wepKeys[0] = "\"" + Password + "\"";
//            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
//            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
//            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
//            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
//            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
//            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//            config.wepTxKeyIndex = 0;
//        }
//        if (Type == WifiCipherType.WIFICIPHER_WPA) {
//            config.preSharedKey = "\"" + Password + "\"";
//            config.status = WifiConfiguration.Status.ENABLED;
//        } else {
//            return null;
//        }
//        return config;
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";

        WifiConfiguration tempConfig = this.IsExsits(SSID);
        if (tempConfig != null) {
            mWifiManager.removeNetwork(tempConfig.networkId);
        }

        if (Type == WifiCipherType.WIFICIPHER_NOPASS) // WIFICIPHER_NOPASS
        {
//            config.wepKeys[0] = "";
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//            config.wepTxKeyIndex = 0;
        }
        if (Type == WifiCipherType.WIFICIPHER_WEP) // WIFICIPHER_WEP
        {
            config.hiddenSSID = true;
            config.wepKeys[0] = "\"" + Password + "\"";
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        }
        if (Type == WifiCipherType.WIFICIPHER_WPA) // WIFICIPHER_WPA
        {
            config.preSharedKey = "\"" + Password + "\"";
            config.hiddenSSID = true;
            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.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;
        }
        return config;
    }


    /**
     * 切换到指定wifi
     * @param wifiName  指定的wifi名字
     * @param wifiPwd   wifi密码,如果已经保存过密码,可以传入null
     * @return
     */

    public boolean changeToWifi(String wifiName, String wifiPwd ,boolean back){
        if(mWifiManager == null){
            Log.e(TAG, "===wifiManager初始化失败===");
            return false;
        }

        List wifiList = mWifiManager.getConfiguredNetworks();
        WifiConfiguration wfc = null;
        for (int i = 0; i < wifiList.size(); ++i) {
            WifiConfiguration wifiInfo0 = (WifiConfiguration) wifiList.get(i);
            if (wifiInfo0.SSID.contains(wifiName)) {
                Log.e(TAG, "===wifi已连接过===" + wifiInfo0.SSID);
//                return doChange2Wifi(wifiInfo0.networkId);
                wfc = wifiInfo0;
                int anInt = SpUtils.getInt(ConsKeys.CONNECT_TIMES, 0);
                if (anInt <2 && !back){
                    SpUtils.putInt(ConsKeys.CONNECT_TIMES,++anInt);
                    return false;
                }
            }
        }
        Log.e(TAG,"====wificonfig为空====="+(wfc!=null));
        if (wfc!=null) {
            if (mWifiManager.startScan()) {
                List scanResults = mWifiManager.getScanResults();
                for (ScanResult s : scanResults) {
                    Log.e(TAG,"====扫描到wifi名称====="+s.SSID);
                    if (s.SSID.contains(wifiName)) {
                        Log.e(TAG,"====正好扫描到该wifi,现在去连接=====");
                        return doChange2Wifi(wfc.networkId);
                    }
                }
            }
        }

        Log.e(TAG,"======建立新的wifi连接=====");
        if (mWifiManager.startScan()){
            List scanResults = mWifiManager.getScanResults();
            Log.e(TAG,"======扫描得到wifi个数====="+scanResults.size());
            for (ScanResult s:scanResults){
                Log.e(TAG,"======扫描到wifi名称===="+s.SSID);
                if (s.SSID.contains(wifiName)){
                    Log.e(TAG,"====开始连接指定wifi==="+s.SSID);
                    WifiConfiguration wifiNewConfiguration = CreateWifiInfo(s.SSID, wifiPwd,WifiCipherType.WIFICIPHER_NOPASS);
                    int newNetworkId = mWifiManager.addNetwork(wifiNewConfiguration);
                    if (newNetworkId == -1) {
                        Log.e(TAG, "=====操作失败,需要您到手机wifi列表中取消对设备连接的保存====");
                        removeWifi(s.SSID,null);
                    } else {
                        return doChange2Wifi(newNetworkId);
                    }
                }
            }
            return false;
        }else {
            Log.e(TAG,"======开启wifi扫描失败=====");
            return false;
        }
    }

    private boolean doChange2Wifi(int newNetworkId) {
        Log.e(TAG,"=====开始切换wifi=====");
        // 如果wifi权限没打开(1、先打开wifi,2,使用指定的wifi)
        if(!mWifiManager.isWifiEnabled()){
            mWifiManager.setWifiEnabled(true);
        }
        boolean enableNetwork = mWifiManager.enableNetwork(newNetworkId, true);
        if (!enableNetwork) {
            Log.e(TAG, "===切换到指定wifi失败===");
            SpUtils.putInt(ConsKeys.CONNECT_TIMES,0);
            return false;
        } else {
            Log.e(TAG, "===切换到指定wifi成功===");
            SpUtils.putInt(ConsKeys.CONNECT_TIMES,0);
            return true;
        }
    }

    public void removeWifi(String wifiName,String wifiPwd){
        if (wifiPwd == null) {
            WifiConfiguration wifiNewConfiguration = CreateWifiInfo(wifiName, wifiPwd, WifiCipherType.WIFICIPHER_NOPASS);
            if (wifiNewConfiguration != null) {
                mWifiManager.removeNetwork(wifiNewConfiguration.networkId);
            }
        }

    }

    // 查看以前是否也配置过这个网络
    public WifiConfiguration isExsits(String SSID) {
        List existingConfigs = mWifiManager
                .getConfiguredNetworks();
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                return existingConfig;
            }
        }
        return null;
    }
}

连接上设备wifi后,使用Socket与设备进行通信,一般放在workthread中:

public Socket socket;

public Runnable socketRunnable = new Runnable() {
    @Override
    public void run() {
        try {
            if (socket != null) {
                if (socket.isConnected()) socket.close();
                if (bReader != null) bReader.close();
                if (os != null) os.close();
            }
            isReceivedNoData = true;
            socket = new Socket();
            socket.connect(new InetSocketAddress("192.168.4.1", 5120), 5000);
            socket.getKeepAlive();
            os = socket.getOutputStream();
            InputStream is = socket.getInputStream();
            //解析服务器返回的数据
            bReader = new BufferedInputStream(is);

            getData();
            sendData();
        } catch (Exception e) {
            socketConthread = null;
            isReceivedNoData = true;
            socket = null;
            Log.e(TAG, "======SOCKET连接异常======");
            h.sendEmptyMessageDelayed(CONNECTED_SOCKET, 2000);
            e.printStackTrace();
        }
    }
};

socket地址由设备放提供,一般客户的设备地址是一样的。

socket通信建立后则是读写通信内容,读写单独放到子线程中执行,使用eventbus或者接口回调处理通信内容:

public void getData(){

new Runnable() {
    @Override
    public void run() {
        h.sendEmptyMessageDelayed(CONNECTED_SOCKET, 8000);
        while (!readErr && !isTimeOut) {
            try {
                Thread.sleep(1000);
                if (bReader != null) {
                    int available = bReader.available();
                    byte[] b = new byte[available];
                    int len = bReader.read(b); 
                    String strRec = HexUtil.bytesToHexString(b);
                    Log.e(TAG, "====读取socket消息=====" + strRec);    
                } 
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}.start();

public void sendData(){

new Runnable() {
    @Override
    public void run() {
        try {
            Log.e(TAG, "===向服务器发送数据流====");
            os.write("aa".getBytes());
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}.start();

最好将这两个线程定义出来,方便在退出是销毁,特别是如果接触了刷新view的操作,更需要谨慎使用,否则容易内粗溢出。

欢迎大家指点错误!!!

 

 

你可能感兴趣的