【问题标题】:issues with one to many mobile device file transfer in android using wifi direct使用wifi直接在android中进行一对多移动设备文件传输的问题
【发布时间】:2015-06-07 11:50:48
【问题描述】:

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

但我在使用 WiFi direct 时面临的问题是,它在保持连接和查找其他设备方面不一致。

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

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

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

【问题讨论】:

  • 我从同样的想法开始,最后最终使用了 Wifi-Hotspot。看看它...
  • 你有什么指点吗?\
  • @unrealsoul007 能否请您指导我从哪里实施 Wi-fi 热点。提前致谢。

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


【解决方案1】:

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

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

  1. 创建热点
  2. 连接到一个。

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

希望这些都是您需要的所有指针..!!

【讨论】:

  • 我明白你在说什么,但是我如何访问ClientScanResult 的代码,因为它包含 IP 和其他信息
  • “我如何访问ClientScanResult 的代码”是什么意思?你能再解释一下吗..?
  • 好吧,我需要范围内的设备列表及其 IP 太正确,才能启动连接和共享文件
  • IP 只有在其中一台设备调用 connectToHotspot 后才可用。然后要获取连接到热点的设备的IP,您可以从splitted[0]获取它的IP。 Splitted[0] 是 IP,splitted[3] 是 mac。对不起,我没有添加一个类 ClientScanResult。
  • 更新了答案。现在 resultIpAddr 包含连接到热点的所有设备的 IP 地址。
【解决方案2】:

Wifi direct 作为一种技术是对等通信的理想选择。但是谈到 wifi direct for android 时,它只适用于只有 1-1 用例的单个连接。可以创建一对多每个设备都连接到组所有者(软 AP)。但即使您建立一对一并尝试扩展到多用例,您也会遇到某些无法完美连接的设备的问题。设备卡在受邀状态。查看下载此应用后出现的一些问题https://play.google.com/store/apps/details?id=com.budius.WiFiShoot&hl=en

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

【讨论】:

  • 能否告诉我如何使用热点实现相同的功能,宝贵地通过编程?
猜你喜欢
  • 1970-01-01
  • 2022-10-06
  • 2014-01-21
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多