其他分享
首页 > 其他分享> > Android:在屏幕关闭时进入覆盖范围区域后重新连接到Wi-Fi

Android:在屏幕关闭时进入覆盖范围区域后重新连接到Wi-Fi

作者:互联网

只要设备在接入点范围内而不打开屏幕,我就一直在自动打开Wi-Fi.测试和找出解决方案非常令人沮丧,尤其是因为不同的设备具有完全不同的结果.

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

>走出WiFi覆盖范围并在那里呆一分钟.
>返回到覆盖范围.

结果:Wifi没有立即重新连接,因此应用程序没有重新连接到服务器.根据设备和设置的不同,有时直到打开屏幕后它才完全重新连接.

强制Wi-Fi重新连接
好的,这一次,如果Wifi断开连接,我的应用程序将间隔调用WifiManager.Reconnect().

重复测试.
结果:为S3工作,其他设备失败.

尝试添加其他电话
尝试了WifiManager.Scan(),WifiManager.Reassociate()等的不同组合.最终,它适用于除S4之外的大多数设备(HTC,S3).

似乎适用于所有设备的代码

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

我什至不确定所有这些代码是否必要,因为我无法在线找到很多信息. WifiFixer确实帮助了一些人.但这似乎确实适用于我测试过的设备.

问题

>还有更好的方法吗?
>制造商是否真的在修改基本的Android,使我看到很大的不同?
>这是完全错误的方法吗?

感谢您阅读所有这些内容:)

补充笔记

>代码在从AlarmManager启动的10秒间隔内运行. WakeLock仅在此通话期间保持.
>在此最终看起来恐怖的解决方案/破解之前,“ Wifi睡眠策略”影响了结果.这让我感到困惑,因为我一直都拿着WifiLock,我认为这相当于“从不”.
>以编程方式更改“ Wifi睡眠策略”不适用于S4,其他人可以确认吗?
>是的,我们特别需要这样做,并且了解电池的影响.

解决方法:

我的情况略有不同-我不持有wifi锁开始(而且我使用的是常规android系统,因此我必须翻译您的方法).

屏幕关闭,CPU关闭,无线电消失.警报唤醒我的(唤醒)服务-我持有(部分)唤醒锁.

我想要的是-如果启用了wifi可以将其连接到在无线电失效之前已连接的接入点-我将获得一个wifi锁,然后调用您的函数-wakeWifiUp().无线电失效后(!wifiInfo.IsConnectedOrConnecting为true),当我尝试连接时,网络无法访问.我解决它,如:

public final class NetworkService extends WakefulIntentService {

    // this is an intent service - runs on its own thread - otherwise it would
    // deadlock as I am using it. Moreover it holds a wakelock and woken up by
    // an AlarmManager's Receiver - works reliably
    private BroadcastReceiver mConnectionReceiver;
    private volatile static CountDownLatch latch;

    @Override
    protected void doWakefulWork(Intent intent) {
        WifiLock _wifiLock = null;
        WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        boolean failedToConnect = true;
        if (wm != null && wm.isWifiEnabled()) {// Don't want to enable it myself
            _wifiLock = wm.createWifiLock(
            /* WifiManager.WIFI_MODE_FULL_HIGH_PERF */0x3, this.getClass()
                .getName() + ".WIFI_LOCK");
            _wifiLock.acquire();
            failedToConnect = !wakeWifiUp();
        }
        if (failedToConnect) {
            if (_wifiLock != null) _wifiLock.release();
            w("No connection !");
            return;
        }
        HttpURLConnection connection = null;
        try {
            connection = connection(); 
        } catch (IOException e) {/* won't throw - it doesn't do much*/}
        OutputStream serverOutputStream = null;
        try {
            serverOutputStream = connection.getOutputStream(); // now
            // this is really where the connection might seriously throw
            // .... Work ....
        } catch (IOException e) {
            w("IOException sending data " + e.getMessage());
            // I get here : Network unreachable when radio dies
        } finally {
            if (_wifiLock != null) _wifiLock.release();
            if (connection != null) connection.disconnect();
        }
    }

    private HttpURLConnection connection() throws MalformedURLException,
            IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL("localhost")
            .openConnection();
        connection.setDoOutput(true); // triggers POST
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("User-Agent",
            "Android Multipart HTTP Client 1.1");
        return connection;
    }

    private boolean wakeWifiUp() {
        ConnectivityManager _androidConnectivityMgr = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo wifiInfo = _androidConnectivityMgr
            .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        WifiManager _wifiManager = (WifiManager)
                getSystemService(Context.WIFI_SERVICE);
        final int wifiState = _wifiManager.getWifiState();
        if (!_wifiManager.isWifiEnabled()
            || wifiState == WifiManager.WIFI_STATE_DISABLED
            || wifiState == WifiManager.WIFI_STATE_DISABLING) {
            // Make sure the Wi-Fi is enabled, required for some devices when
            // enable WiFi does not occur immediately
            d("!_wifiManager.isWifiEnabled()");
            _wifiManager.setWifiEnabled(true);
            // do not enable if not enabled ! FIXME
            return false;
        }
        if (!wifiInfo.isConnectedOrConnecting()) {
            d("Wifi is NOT Connected Or Connecting - "
                + "wake it up and wait till is up");
            // Do not wait for the OS to initiate a reconnect to a Wi-Fi router
            _wifiManager.pingSupplicant();
            if (wifiState == WifiManager.WIFI_STATE_ENABLED) {
                try {
                    // Brute force methods required for some devices
                    _wifiManager.setWifiEnabled(false);
                    _wifiManager.setWifiEnabled(true);
                } catch (SecurityException e) {
                    // 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();
            // THIS IS WHAT I DO TO WAIT FOR A CONNECTION
            try {
                mConnectionReceiver = new WifiConnectionMonitor();
                startMonitoringConnection();
                latch = new CountDownLatch(1);
                w("I wait");
                latch.await();
                w("Woke up");
                return true; // made it
            } catch (InterruptedException e) {
                w("Interrupted while waiting for connection", e);
                return false;
            } finally {
                stopMonitoringConnection();
            }
        }
        return true;
    }

    static void downTheLatch() {
        latch.countDown();
    }

    private synchronized void startMonitoringConnection() {
        IntentFilter aFilter = new IntentFilter(
            ConnectivityManager.CONNECTIVITY_ACTION);
        aFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        registerReceiver(mConnectionReceiver, aFilter);
    }

    private synchronized void stopMonitoringConnection() {
        unregisterReceiver(mConnectionReceiver);
    }

    private final class WifiConnectionMonitor extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent in) {
            String action = in.getAction();
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                NetworkInfo networkInfo = in
                    .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                d(networkInfo + "");
                if (networkInfo.isConnected()) {
                    d("Wifi is connected!");
                    NetworkService.downTheLatch(); // HERE THE SERVICE IS WOKEN!
                }
            }
        }
    }
}

顺便说一句,并不是需要用akeWifiUp()中的所有技巧(在我的情况下),也可以省略所有!_wifiManager.isWifiEnabled()-因为只有在用户启用的情况下,我才使用网络.我将其保留完整.

回顾一下:在我的场景中,您的方法还不够(如果我正确地翻译成java并且没有犯一些愚蠢的错误,这种错误总是适用的-另请参见我的connection()).我需要等待建立连接-但是一切都很好.不确定您使用它的方式是否正确-如果像我一样,那可能是您一直持有wifi锁

HTC Nexus 1、2.3.7,Cyanogen mod(不要射击,我已经给它进行了测试).

会及时向大家发布

标签:xamarin-android,android-wifi,wifimanager,android
来源: https://codeday.me/bug/20191122/2061709.html