使用wifi直接

时间:2015-06-07 11:50:49

标签: android android-wifi wifi-direct wifip2p android-wireless

我正在尝试创建一个应用程序,其中一个Android应用程序可以将文件(文本,视频,照片)传输到其他多个Android设备。最初我想在Android中使用wifi直接在多个设备上共享文件。

但我直接面对WiFi的问题是,它在维护连接和寻找其他设备方面存在不一致。

1)有时应用程序必须等待大约5分钟或更长时间,之后才能连接。

2)多次通过其他设备的对话接受邀请后,将连接更改为connected状态需要花费大量时间,直到此时设备无法获取其他设备的IP地址。

在经历了不一致之后,我想放弃使用wifi直接的想法。有没有人有更好的建议FASTER将多个文件从一个移动设备转移到另一个没有接入点的设备。

2 个答案:

答案 0 :(得分:3)

Hotspot使用使用Reflection调用的隐藏方法。从本质上讲,热点是其他人在连接到普通wifi网络时可以连接的接入点。

如上所述,它是一个接入点,因此它们是需要支持的两个主要功能

  1. 创建热点
  2. 连接到一个。
  3. <强> 1。创建热点

    /**
         * Start AccessPoint mode with the specified
         * configuration. If the radio is already running in
         * AP mode, update the new configuration
         * Note that starting in access point mode disables station
         * mode operation
         * @param wifiConfig SSID, security and channel details as part of WifiConfiguration
         * @return {@code true} if the operation succeeds, {@code false} otherwise
         */
        public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
            try {
                if (enabled) { // disable WiFi in any case
                    mWifiManager.setWifiEnabled(false);
                }
    
                Method method = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
                return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
            } catch (Exception e) {
                Log.e(this.getClass().toString(), "", e);
                return false;
            }
        }
    

    使用密码设置热点(以下示例中为WPA2)

    WifiConfiguration wifiCon = new WifiConfiguration();
    wifiCon.SSID = "ssid";
    wifiCon.preSharedKey = "password";
    wifiCon.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
    wifiCon.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
    wifiCon.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
    wifiCon.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
    try
    {
        Method setWifiApMethod = wm.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
        boolean apstatus=(Boolean) setWifiApMethod.invoke(wm, wifiCon,true);
    } 
    catch (Exception e) 
    {
        Log.e(this.getClass().toString(), "", e);
    }
    

    <强> 2。连接到热点

    public Boolean connectToHotspot(WifiManager wifiManager, String ssid) 
        {
            this.wifiManager = wifiManager;
            WifiConfiguration wc = new WifiConfiguration();
            wc.SSID = "\"" +encodeSSID(ssid) +"\"";
            wc.preSharedKey  = "\"" + generatePassword(new StringBuffer(ssid).reverse().toString())  +  "\"";
            wifiManager.addNetwork(wc);
            List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
            for( WifiConfiguration i : list ) {
                if(i!=null && i.SSID != null && i.SSID.equals(wc.SSID)) 
                {
                     wifiManager.disconnect();
                     boolean status = wifiManager.enableNetwork(i.networkId, true);
                     wifiManager.reconnect();               
                     return status;
                }
             }
            return false;
        }
    

    想到这一点,您可能还需要连接到热点的设备列表

    /**
         * Gets a list of the clients connected to the Hotspot, reachable timeout is 300
         * @param onlyReachables {@code false} if the list should contain unreachable (probably disconnected) clients, {@code true} otherwise
         * @param finishListener, Interface called when the scan method finishes
         */
        public void getClientList(boolean onlyReachables, FinishScanListener finishListener) {
            getClientList(onlyReachables, 300, finishListener );
        }
    /**
     * Gets a list of the clients connected to the Hotspot 
     * @param onlyReachables {@code false} if the list should contain unreachable (probably disconnected) clients, {@code true} otherwise
     * @param reachableTimeout Reachable Timout in miliseconds
     * @param finishListener, Interface called when the scan method finishes 
     */
    
    public void getClientList(final boolean onlyReachables, final int reachableTimeout, final FinishScanListener finishListener) {
    
    Runnable runnable = new Runnable() {
        public void run() {
    
            BufferedReader br = null;
            final ArrayList<String> resultIPAddr = new ArrayList<String>();
    
            try {
                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)) {
                        // Basic sanity check
                        String mac = splitted[3];
    
                        if (mac.matches("..:..:..:..:..:..")) {
                            boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);
    
                            if (!onlyReachables || isReachable) {
                                resultIPAddr.add(splitted[0]);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                Log.e(this.getClass().toString(), e.toString());
            } finally {
                try {
                    br.close();
                } catch (IOException e) {
                    Log.e(this.getClass().toString(), e.getMessage());
                }
            }
    
            // Get a handler that can be used to post to the main thread
            Handler mainHandler = new Handler(context.getMainLooper());
            Runnable myRunnable = new Runnable() {
                @Override
                public void run() {
                    finishListener.onFinishScan(result);
                }
            };
            mainHandler.post(myRunnable);
        }
    };
    
    Thread mythread = new Thread(runnable);
    mythread.start();
    }
    

    此外,您可能需要扫描附近的Wifi网络以连接网络。

    //This can be done by getting WifiManager's instance from the System.
    
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    wifiManager.getScanResults();
    
    // The above is an async call and will results are available System will broadcast `SCAN_RESULTS_AVAILABLE` intent and you need to set a `BroadCastReceiver` for it.
    
    // And get the results like this 
    
    List<ScanResult> results = wifiManager.getScanResults();
    

    希望这些都是你需要的指针.. !!

答案 1 :(得分:0)

Wifi直接作为一种技术是对等通信的理想选择。然而,谈到wifi直接用于Android,它只适用于只有1-1用例的单个连接。它可以创建一对多每个设备都连接到组所有者(Soft AP)。但即使你构建一对一并尝试扩展到多用例,你也会遇到某些没有完美连接的设备的问题。设备陷入邀请状态。下载此应用程序https://play.google.com/store/apps/details?id=com.budius.WiFiShoot&hl=en

后,查看问题中列出的一些问题

如果你想进行多重连接,最好使用热点。一个设备最终成为热点,其他客户端连接到热点。它正被许多应用程序使用,如xender,zapiya。