当前位置:首页 > > 充电吧
[导读]Wifi_Direct是目前设备间最快的无线数据连接方式,速度可以达到40Mb/s。Google从Android 4.0(ICS)开始支持Wifi_Direct,而三星则更早些就在它自己的设备上支持了

Wifi_Direct是目前设备间最快的无线数据连接方式,速度可以达到40Mb/s。Google从Android 4.0(ICS)开始支持Wifi_Direct,而三星则更早些就在它自己的设备上支持了Wifi_Direct。几年来,Wifi_Direct的发展一直不温不火,但是目前市面上支持Wifi_Direct的设备并不是很多。         从目前接触过得设备来看,三星I9100的Wifi_Direct功能其实使用了Wifi的硬件,所以,它在使用Wifi_Direct功能时,无法使用wifi;nexus7、Padfone infinite(A80)则有独立的硬件来支持Wifi_Direct,所以,在使用Wifi_Direct功能的时候,Wifi仍旧可用。
          Android framework提供了一个android.net.wifi.p2p包来提供对于Wifi_Direct的支持,其中包含了7个class和9个interface。其中WifiP2pManager为最核心的class,其他的class和interface都为它所用。
          使用Wifi_P2p需要的Permission有两个:

public static final String ACCESS_WIFI_STATE
Added in API level 1
Allows applications to access information about Wi-Fi networks
Constant Value: "android.permission.ACCESS_WIFI_STATE"


public static final String CHANGE_WIFI_STATE
Added in API level 1
Allows applications to change Wi-Fi connectivity state
Constant Value: "android.permission.CHANGE_WIFI_STATE"

        Wifi_Direct的大致配对流程如下:

        1. WifiP2pManager.discoverPeers()开始扫描设备         2. 获取扫描到的设备,选择其中一个设备进行连接配对WifiP2pManager.connect         3. 配对成功后,根据WifiP2pInfo.isGroupOwner和WifiP2pInfo.groupOwnerAddress进行连接。

        个人认为Wifi_Direct配对需要注意的问题:         1. Setting中启用/关闭WifiP2p按钮,应该是和Wifi的启用/关闭按钮放在一起了(其实,有些设备的实现中,Wifip2p使用的就是wifi的硬件),所以使用WifiP2p功能需要开启Wifi。         2. Setting中BlueTooth有一个“让自己可见”的按钮,而Wifi_Direct没有这样的设置,仅提供了一个启动scan的按钮。本人尚未明确在未启动scan的情况下,设备对于其他wifi_direct是否是可见的,但是可以明确scan中的wifi_direct设备对其他设备来说是可见的。所以,建议需要进行配对的两台Wifi_Direct设备都进行scan。         3. 配对成功的前提条件是:进行配对的两台设备都必须能够扫描到对方。所以,两台设备都进行scan操作的根本原因在这里。         4. 开发者无法决定GroupOwner是哪台设备,但是可以通过WifiP2pConfig.groupOwnerIntent参数进行建议。
        从测试的结果来说,Wifi_Direct的表现受具体设备的影响很大,配对的速度也有较大差异,从10秒到2分钟甚至更久。大概的来说,nexus7成功的概率较高,个人感觉可以达到70%的成功率,Padfone infinite(A80)的成功率在50%以下。                    为了兼容传统的Wifi设备,Wifi_Direct其实还存在另一种使用方式,暂且称为兼容模式。兼容模式的特点在于,只需要担任GroupOwner的设备支持Wifi_Direct,而其他设备只需要支持传统的Wifi就可以了(个人觉得其实这种使用模式很像Android的便携热点功能)。          操作流程为:          1. 支持Wifi_Direct的设备创建group,WifiP2pManager.createGroup(),成为GroupOwner。          2.  其他设备扫描Wifi_Direct设备创建group后产生的Wifi热点并连接即可。
         兼容模式存在的一个问题是:因为作为group member的设备是使用Wifi硬件接入到group中,所以会导致member进行wifi 热点切换以及网络中断,可能对正在进行的网络操作造成影响,而group owner则不存在这个问题。另外,而WifiP2p配对的使用方式,WifiP2p和Wifi可以独立运作,相互不受影响。                     但是,兼容模式因为省去了扫描和配对的过程,所以建立连接的成功率明显提升,并且建立连接的速度要快不少(具体时间比较随机)。           从个人的使用感觉来讲,这WifiP2p这套API接口高度的异步化,API都需要以回调的方式获取操作结果(包内interface比较多的原因就在于此)。更加麻烦的是,几个关键API(例如WifiP2pManager.connect)的回调获取到的结果仅仅是执行是否开始,真正的结果还得注册broadcast receiver,通过监听广播来获得,才能进行下一步操作。异步的设计提高了代码的逻辑复杂度。

         使用NFC来实现WifiP2p的连接:          1. 使用NFC将owner设备创建的group的SSID和密码传递给member设备          2. owner开始监听指定端口,等待member的连接          3. member接收到nfc传递过来的数据后,根据SSID和密码连接到group          4. 连接成功以后,过去owner设备的ip地址(获取gateway ip即可),连接到owner的指定端口

          常见问题:           1. WifiP2p相关的广播有哪些,各自有哪些参数?
WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION:当WifiP2p扫描开始或者停止时,触发该广播 该广播包含一个int型extra, key为WifiP2pManager.EXTRA_DISCOVERY_STATE,其值为WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED或者WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED.
WifiP2pManager.WIFI_P2P_STATE_CHANGED_ATIONIC:当WifiP2p状态发生变化时触发(如果WifiP2p可用,那么当BroadcastReceiverregister时,也会收到该广播) 该广播包含一个int型extra,key为WifiP2pManager.EXTRA_WIFI_STATE,其值为WifiP2pManager.WIFI_P2P_STATE_ENABLED或者WifiP2pManager.WIFI_P2P_STATE_DISABLED。
WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:当设备的WifiP2p状态发生变化时触发广播(如果WifiP2p可用,那么当BroadcastReceiverregister时,也会收到该广播) 该广播包含一个类型为WifiP2pDevice的extra,key为WifiP2pManager.EXTRA_WIFI_P2P_DEVICE.
WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION:当WifiP2p扫描时,发现device列表发生变化时,触发该广播 该广播不含extra,开发者应该接收到此广播后,调用WifiP2pManager.requestPeers()函数查询当前设别列表。
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION:当WifiP2p的group发生变化时,触发该广播。 该广播包含两个extra: key:WifiP2pManager.EXTRA_NETWORK_INFO,其值为NetworkInfo类型。 key:WifiP2pManager.EXTRA_P2P_INFO,其值为WifiP2pInfo类型。 PS:这里的WifiP2p group发生变化包含如下情况: 1. 建立group 2. member加入到group 3. member退出group 4. 关闭group
        2. 如何获得WifiP2pGroupInfo,它有什么用? WifiP2pManager.requestGroupInfo()函数,可以获取GroupInfo,较为有用的api有: 1. GroupInfo.getClientList()可以获得连接到group的member列表 2. GroupInfo.getNetWorkName()可以获得group的wifi热点名称(SSID) 3. GroupInfo.getPassphrase() 可以获得连接到wifi 热点的密码
        3. 如何获得WifiP2pInfo? 可以从WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION广播中的extra中获取 也可以从WifiP2pManager.requestConnectionInfo()函数获取。
        4. 如何防止配对产生的提示框? 在不修改framework的情况下,本人暂时为找到可行的方案。 这个提示狂是由系统提供的,具体表现视设备而定。nexus只在第一次配对的时候弹出,而A80每一次配对都会弹出。 但是,使用兼容模式使用Wifi_Direct是没有提示框的。
         5. 如何实现wifi热点的连接?  经过测试,在A80上,如下代码可以实现连接到热点。

            // build a wifi config
            final WifiConfiguration config = new WifiConfiguration();
            config.allowedAuthAlgorithms.clear();
            config.allowedPairwiseCiphers.clear();
            config.allowedGroupCiphers.clear();
            config.allowedKeyManagement.clear();
            config.allowedProtocols.clear();

            config.SSID = """ + ssid + """;//设定ssid
            config.preSharedKey = """ + pw + """;//设定密码
            config.hiddenSSID = false;
            config.status = WifiConfiguration.Status.ENABLED;
            config.priority = 1;
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedPairwiseCiphers.set(3);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

            // connect to ap
            int id = WifiManager.addNetwork(config);
            config.networkId = id;
            if (id != -1 && mWifiManager.enableNetwork(id, true)) {
                ....
            }


        6. 如何通过代码开启便携热点?(这个问题和Wifi_Direct无关,但是可以让不支持Wifi_Direct的Android设备获得类似模拟模式的效果,可能和快牙的实现方式相似)
正常情况下,开启便携热点的API因为hide隐藏的关系,无法被apk调用,仅原生app可以调用。但是用java的反射机制可以让普通app也能调用这个api,实现如下: // wifi热点开关       public boolean setWifiApEnabled(boolean enabled) {           if (enabled) { // disable WiFi in any case               //wifi和热点不能同时打开,所以打开热点的时候需要关闭wifi               wifiManager.setWifiEnabled(false);           }           try {               //热点的配置类               WifiConfiguration apConfig = new WifiConfiguration();               //配置热点的名称(可以在名字后面加点随机数什么的)               apConfig.SSID = "YRCCONNECTION";               //配置热点的密码               apConfig.preSharedKey="12122112";                   //通过反射调用设置热点               Method method = wifiManager.getClass().getMethod(                       "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);               //返回热点打开状态               return (Boolean) method.invoke(wifiManager, apConfig, enabled);           } catch (Exception e) {               return false;           }       }   以上代码拷贝自:http://blog.csdn.net/luoboo525/article/details/7883998

        7. WifiP2pManager.discovePeers仅仅返回附近有哪些设备开启了wifi p2p,而app的实际使用场景,往往希望寻找可以提供某些特定服务的设备。例如同一房间内,有A,B,C,D四台设备开启了wifi p2p,而A设备和B设备都安装了app1,C设备和D设备都安装了app2,使用者希望A设备能和B设备配对连接,而C设备与D设备连接,运行在A设备上的app1如何识别它应该连接的是B设备,而非C、D设备呢?
        为了支持更加个性化的设备发现,WifiP2pManager支持UPNP和DNS两种方式的设备(服务?)发现。         App可以通过WifiP2pManager.addLocalService来向周边的设备广播自己支持哪些服务。         也可以通过如下步骤实现发现这些服务:         1. 通过WifiP2pManager.addServiceRequest()添加服务请求         2. 通过WifiP2pManager.discoverService()开始服务发现         3. 通过WifiP2pManager.setDnsSdResponseListener()或者WifiP2pManager.setUpnpServiceResponseListener()监听服务内容。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭