Wifi duerme, incluso con Lock

Resumen: incluso cuando se adquiere el locking wifi, cuando el teléfono funciona con baterías, WiFi se desconecta después de un tiempo.

Simplifiqué el problema a una sola actividad con un botón que lanza un hilo. Simplemente envía 100.000 cadenas a un servidor de eco que se ejecuta en una PC (una cadena cada 100 ms). Vea el código a continuación. Puedo ver el tráfico con WireShark, y también el servidor de eco muestra las cadenas. Observe cómo se adquieren los lockings de WiFi y de alimentación antes de comenzar a enviar (y liberados después, por supuesto).

Sin embargo, cuando el teléfono funciona con batería y el usuario apaga el teléfono, sigue enviando cadenas durante un tiempo y luego se desconecta la WiFi y el teléfono ni siquiera responde al ping. Se necesitan entre 600 y 6000 para desconectarse (las cifras son así de redondas, por lo que creo que son importantes).

Funciona perfectamente cuando el A / C está conectado, así que supongo que está relacionado de alguna manera con la administración de energía.

Para probarlo, simplemente inicie la actividad, inicie el servidor de eco, inicie WireShark, presione el botón “Inicio” ( android:onClick="doStart" ), bloquea el teléfono y déjelo sobre la mesa. Voy a almorzar o lo que sea y después de 600-6000s puedo ver los errores de tx en WireShark, el servidor de eco ha dejado de recibir tráfico y el teléfono no responde al ping.

El teléfono es 2.2, con la política WiFi configurada para “dormir después de 15 m”.

 package Odroid.test; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.Date; import android.app.Activity; import android.content.Context; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.PowerManager; import android.view.View; import android.widget.Button; public class Test extends Activity { PowerManager _powerManagement = null; PowerManager.WakeLock _wakeLock = null; WifiManager.WifiLock _wifiLock = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void doStart(View v) { DoerThreadFake t = new DoerThreadFake(); t.start(); } private class DoerThreadFake extends Thread { public void run() { runOnUiThread(new Runnable() { public void run() { ((Button) findViewById(R.id.start)).setText("Doing..."); } }); _keepOnStart(); Socket s; byte[] buffer = new byte[1000]; try { s = new Socket("192.168.0.16", 2000); PrintStream ps = new PrintStream(s.getOutputStream()); InputStream is = s.getInputStream(); for (int i = 0; i  0) { int a = is.available(); if (a > 1000) a = 1000; is.read(buffer, 0, a); // Clean echo } } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } _keepOnStop(); runOnUiThread(new Runnable() { public void run() { ((Button) findViewById(R.id.start)).setText("Done"); } }); } private void _keepOnStart() { if (_powerManagement == null) { _powerManagement = (PowerManager) getSystemService(Context.POWER_SERVICE); } if (_wakeLock == null) { _wakeLock = _powerManagement.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "0 Backup power lock"); } _wakeLock.acquire(); WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); if (wifiManager != null) { _wifiLock = wifiManager.createWifiLock("0 Backup wifi lock"); _wifiLock.acquire(); } } private void _keepOnStop() { if ((_wifiLock != null) && (_wifiLock.isHeld())) { _wifiLock.release(); } if ((_wakeLock != null) && (_wakeLock.isHeld())) { _wakeLock.release(); } } } } 

El manifiesto:

                 

¿Alguna idea?

Existen numerosos errores en el rastreador de fallas de Android relacionados con el modo de ahorro / ahorro de energía wifi e incluso las aplicaciones disponibles que intentan rectificar esto. Por lo tanto, es bastante probable que no estés haciendo nada mal.

http://code.google.com/p/android/issues/detail?id=9781
http://code.google.com/p/android/issues/detail?id=1698

También echa un vistazo a wififixer, que es un proyecto de código abierto que puede ayudarte con el código para mantener viva la conexión

http://wififixer.wordpress.com/