安卓:进入覆盖范围,同时屏幕关闭后重新连接到Wi-Fi [英] Android : Reconnect to Wi-Fi after entering coverage area while screen turned off

查看:312
本文介绍了安卓:进入覆盖范围,同时屏幕关闭后重新连接到Wi-Fi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在挣扎的Wi-Fi自动关闭,一旦设备在接入点的范围内无需转动屏幕上。这是非常令人沮丧的测试,并找出解决的办法,尤其是因为不同的设备有完全不同的结果。

基础测试
保持此测试期间关闭屏幕。该应用程序应持有WifiLock。

  1. 在走出WiFi覆盖,并在那里呆上一分钟。
  2. 在步行回的报道。

结果:WiFi是不会立即重新连接,因此应用程序不会重新连接到服务器。根据设备和设置上,有时它不会重新连接所有,直到屏幕被打开。

强制无线网络重新连接
好了,这时候我的应用程序的,如果WiFi是断开的间隔调用WifiManager.Reconnect()。

反复测试。 结果:曾为S3,没有其他设备

尝试添加一些其他的电话
WifiManager.Scan的尝试不同的组合(),WifiManager.Reassociate(),...等等。最终,这是工作的大多数设备(HTC,S3)除了S4。

code,似乎工作的所有设备

 的NetworkInfo wifiInfo = _androidConnectivityMgr.GetNetworkInfo(ConnectivityType.Wifi);
如果(!_wifiManager.IsWifiEnabled || _wifiManager.WifiState == WifiState.Disabled || _wifiManager.WifiState == WifiState.Disabling)
{
    //确保Wi-Fi已启用,需要一些设备时,启用无线网络不会立即发生
    _wifiManager.SetWifiEnabled(真正的);
}

如果(!wifiInfo.IsConnectedOrConnecting)
{
    //不要等待操作系统启动重新连接到Wi-Fi路由器
    _wifiManager.PingSupplicant();
    如果(_wifiManager.WifiState == WifiState.Enabled)
    {
        尝试
        {
            需要一些设备//暴力方法
            _wifiManager.SetWifiEnabled(假);
            _wifiManager.SetWifiEnabled(真正的);
        }
        赶上(java.lang.SecurityException异常)
        {
            //捕获它不应该在大多数设备发生异常。操作系统漏洞细节处:
            // HTTPS://$c$c.google.com/p/android/issues/detail ID = 22036
        }
    }
    _wifiManager.Disconnect();
    _wifiManager.StartScan();
    _wifiManager.Reassociate();
    _wifiManager.Reconnect();
}
 

我甚至不知道这一切的code是必要的,因为我无法在网上找到的信息。 <一href="https://github.com/Zanshinmu/Wifi-Fixer/blob/master/wififixer/src/org/wahtod/wififixer/WFMonitor.java"相对=nofollow> WifiFixer 确实帮助了一些。但这似乎工作为我所测试的设备。

问题

  • 是否有这样做的更好的办法?
  • 请厂家真正修改基本的Andr​​oid,我可以看到这个多大的差别?
  • 这是完全错误的方式来处理这个?

感谢您通过这一切阅读:)

其他注意事项

  1. code期间从AlarmManager发起10+秒的时间间隔运行。 WakeLock为此呼叫期间只开了。
  2. 在这最后的可怕寻找解决方案之前/破解无线睡眠政策影响的结果。这个困惑我,因为我拿着WifiLock的全部时间,我认为是相当于从不的。
  3. 更改无线睡眠政策编程不为S4工作,可其他人证实?
  4. 是的,我们有一个特别需要做到这一点,都知道电池的含义。
解决方案

曾在该地区第二次去转转。虽然上述的解决方案做了我们所有合格的设备上工作,有可能已经不需要太多的电话。此外,我们得到了新的装置,该装置解决方案没有奏效。这里是一个更好的解决方案:

每隔一段时间这个code被称为

 的NetworkInfo wifiInfo = _androidConnectivityMgr.GetNetworkInfo(ConnectivityType.Wifi);
如果(!wifiInfo.IsConnectedOrConnecting)
{
    //需要确保CPU不会进入睡眠状态之前,下面的异步调用是完成
    _wifiScanWakeLock.Acquire();

    //不要等待操作系统启动重新连接到Wi-Fi路由器
    _wifiManager.StartScan();
}
 

  • _wifiScanWakeLock只是一个局部的,非引用计数WakeLock,部署在的OnDestroy

当Wi-Fi无线扫描完成

 私人无效OnWifiScanResultsReceived(意向结果)
{
    的NetworkInfo wifiInfo = _androidConnectivityMgr.GetNetworkInfo(ConnectivityType.Wifi);
    如果(!wifiInfo.IsConnectedOrConnecting)
    {
        字典&LT;字符串,INT&GT; savedNetworks =新字典&LT;字符串,INT&GT;();
        的foreach(在_wifiManager.ConfiguredNetworks WifiConfiguration配置)
        {
            字符串escapedSsid = Regex.Replace(config.Ssid,^ \| \$,的String.Empty);
            savedNetworks [escapedSsid] = config.NetworkId;
        }

        的foreach(在_wifiManager.ScanResults ScanResult AP)
        {
            INT networkId;
            如果(savedNetworks.TryGetValue(ap.Ssid,出networkId))
            {
                savedNetworks.Remove(ap.Ssid);
                _wifiManager.EnableNetwork(networkId,假);
            }
        }
    }
    _wifiScanWakeLock.Release();
}
 

  • BSSID为WifiConfiguration总是空的,不能使用的唯一地比作ScanResult
  • 的BSSID
  • 这是核心code,很明显,你会担心案件的两个相同的SSID和其他优化

I have been struggling with automatically turning on Wi-Fi as soon as the device is within range of an access point without turning on the screen. It has been very frustrating to test and figure out a solution, especially since different devices have completely different results.

Base Test
Keep the screen turned off during this test. The application should hold a WifiLock.

  1. Walk out of WiFi coverage and stay there for a minute.
  2. Walk back into coverage.

Result : The Wifi is not reconnected immediately and thus app does not reconnect to server. Depending on the device and settings, sometimes it would not reconnect at all until the screen was turned on.

Forcing the Wi-Fi to reconnect
Ok, this time my application calls WifiManager.Reconnect() at an interval if Wifi is disconnected.

Repeated the test. Results : Worked for the S3, failed for other devices.

Tried adding some other calls
Tried different combinations of WifiManager.Scan(), WifiManager.Reassociate(), ...etc. Eventually it was working for most devices(HTC, S3) except the S4.

Code that seems to work for all devices

NetworkInfo wifiInfo = _androidConnectivityMgr.GetNetworkInfo(ConnectivityType.Wifi);
if (!_wifiManager.IsWifiEnabled || _wifiManager.WifiState == WifiState.Disabled || _wifiManager.WifiState == WifiState.Disabling)
{
    // Make sure the Wi-Fi is enabled, required for some devices when enable WiFi does not occur immediately
    _wifiManager.SetWifiEnabled(true);
}

if (!wifiInfo.IsConnectedOrConnecting)
{
    // Do not wait for the OS to initiate a reconnect to a Wi-Fi router
    _wifiManager.PingSupplicant();
    if (_wifiManager.WifiState == WifiState.Enabled)
    {
        try
        {
            // Brute force methods required for some devices
            _wifiManager.SetWifiEnabled(false);
            _wifiManager.SetWifiEnabled(true);
        }
        catch (Java.Lang.SecurityException)
        {
            // Catching exception which should not occur on most devices. OS bug details at :
            // https://code.google.com/p/android/issues/detail?id=22036
        }
    }
    _wifiManager.Disconnect();
    _wifiManager.StartScan();
    _wifiManager.Reassociate();
    _wifiManager.Reconnect();
}

I am not even sure all this code is necessary as I was unable to find much information online. WifiFixer did help some. But this does seem to work for the devices I have tested on.

The Question

  • Is there a better way of doing this?
  • Do the manufacturers really modify the base Android where I can be seeing this much of a difference?
  • Is this completely the wrong way to approach this?

Thanks for reading through all this :)

Additional Notes

  1. Code runs during 10+ second interval initiated from the AlarmManager. WakeLock is held only for the duration of this call.
  2. Before this final scary looking solution/hack the "Wifi Sleep Policy" affected the results. This confused me since I am holding a WifiLock the entire time, which I thought was equivalent of "Never".
  3. Changing the "Wifi Sleep Policy" programmatically does not work for the S4, can anyone else confirm?
  4. Yes, we have a specific need to do this and are aware of battery implication.

解决方案

Had a second go around in the area. While the above solution did work for all our qualified devices, there were too many calls that might have been unnecessary. Plus we got new device for which the solution did not work. Here is a much better solution:

At every interval this code is called

NetworkInfo wifiInfo = _androidConnectivityMgr.GetNetworkInfo(ConnectivityType.Wifi);
if (!wifiInfo.IsConnectedOrConnecting)
{
    // Need to make sure the CPU does not go to sleep before the following async calls are finished
    _wifiScanWakeLock.Acquire();

    // Do not wait for the OS to initiate a reconnect to a Wi-Fi router
    _wifiManager.StartScan();
}

  • _wifiScanWakeLock is just a partial, non-reference counted WakeLock, Dispose in OnDestroy

When the Wi-Fi scan is finished

private void OnWifiScanResultsReceived(Intent result)
{
    NetworkInfo wifiInfo = _androidConnectivityMgr.GetNetworkInfo(ConnectivityType.Wifi);
    if (!wifiInfo.IsConnectedOrConnecting)
    {
        Dictionary<string, int> savedNetworks = new Dictionary<string, int>();
        foreach (WifiConfiguration config in _wifiManager.ConfiguredNetworks)
        {
            string escapedSsid = Regex.Replace(config.Ssid, "^\"|\"$", String.Empty);
            savedNetworks[escapedSsid] = config.NetworkId;
        }

        foreach (ScanResult ap in _wifiManager.ScanResults)
        {
            int networkId;
            if (savedNetworks.TryGetValue(ap.Ssid, out networkId))
            {
                savedNetworks.Remove(ap.Ssid);
                _wifiManager.EnableNetwork(networkId, false);
            }
        }
    }
    _wifiScanWakeLock.Release();
}

  • BSSID for the WifiConfiguration is always null and cannot be used that to uniquely compare to the BSSID of the ScanResult
  • This is the core code, obviously you would have to worry about case of two identical SSIDs and other optimizations

这篇关于安卓:进入覆盖范围,同时屏幕关闭后重新连接到Wi-Fi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆