Wifi热点

最近在开发手机短距离传输有关的产品,由于蓝牙传输速率有限,采用的是wifi热点的方式。

1.WIFI热点的操作需要以下权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

2.WIFI热点的打开

分为三个阶段:1  android 7.0及以前    可以用动态代码的方法设置wifi热点并打开。

                         2. android7.1~android8.0以前      用之前的方法打开后,打开wifi热点端的IP地址却无法分配,导致无法连接到该wifi热点,即打开无效。看某些应用的处理方法为跳转到设置界面提示用户自己进行手动打开。 但因此无法获得wifi热点的密码。

网上有通过startTethering方法动态打开wifi热点的方法,但该方法为系统方法,无法通过反射进行调用,于是采用修改ConnectivityManager源码,将TETHERING_WIFI字段、startTethering方法及OnStartTetheringCallback类中隐藏相关的标志去掉,然后单独编译一个jar包。最后将jar包拷贝到工程中的方法。但个人水平有限,无法进行验证。

                        3.android8.0 可以通过打开wifi热点,并在其回调函数中获取wifi热点名称和wifi热点密码,但该wifi热点名称和密码都是随机的,无法在打开wifi热点前知道,而且每次打开都会变化。

 

以下为最常用方法:(可设置无密码,WPA_EAP,WPA2_PSK三种安全方式,以下为WPA2_PSK方式)

public void createWifitHot(String name, String password) {
        try {
            //wifi和热点不能同时打开,所以先判断wifi是否打开,打开则关闭
            if (mWifiManager.isWifiEnabled()) {
                mWifiManager.setWifiEnabled(false);
            }
            //java反射机制得到Method
            Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",      WifiConfiguration.class, boolean.class);
            //配置热点信息
            WifiConfiguration config = new WifiConfiguration();
            config.SSID = name;
            config.preSharedKey = password;
            config.hiddenSSID = true;
            config.status = WifiConfiguration.Status.ENABLED;
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            //通过java反射调用WifiManager的setWifiApEnabled方法
            method.invoke(mWifiManager, config, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

以下为随机方法:

WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        //cancelLocalOnlyHotspotRequest 是关闭热点
        //打开热点
        manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback(){

            @Override
            public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
                super.onStarted(reservation);
                Log.d(TAG, "Wifi Hotspot is on now");
            }

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

关闭WIFI热点方法如下:

public void closeWifiHotspot() {
        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 (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

至于WIFI热点连接时,如果WIFI连接断开,没有找到 有效的回调方法。只能过段时间查询一次状态判断是否仍在连接。

 

3.WIFI热点的IP地址

 R  热点的IP地址可通过以下方法获取,但连接设备的IP地址无法获取。我采用的方法是设备连接后通过UDP向wifi热点发送数据包,wifi热点在接收到数据包时通过DatagramPacket的getAddress和getPort获得该设备的IP地址及端口号。

    public String getIpAddressFromHotspot(){
        // WifiAP ip address is hardcoded in Android.
        /* IP/netmask: 192.168.43.1/255.255.255.0 */
        String ipAddress = "192.168.43.1";
        DhcpInfo dhcpInfo = mWifiManager.getDhcpInfo();
        int address = dhcpInfo.gateway;
        ipAddress = ((address & 0xFF)
                + "." + ((address >> 8) & 0xFF)
                + "." + ((address >> 16) & 0xFF)
                + "." + ((address >> 24) & 0xFF));
        return ipAddress;
    }
      DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            mDatagramSocket.receive(receivePacket);
            InetAddress inetAddress = receivePacket.getAddress();
            int port = receivePacket.getPort();

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值