Zusammenfassung: Selbst wenn die WLAN-Sperre aktiviert ist, wird das WLAN nach einiger Zeit getrennt, wenn das Telefon mit Batterien betrieben wird.
Ich habe das Problem auf eine einzelne Aktivität mit einer Schaltfläche vereinfacht, die einen Thread startet. Es sendet einfach 100.000 Strings an einen Echoserver, der auf einem PC läuft (ein String alle 100ms). Siehe Code unten. Ich kann den Verkehr mit WireShark sehen und auch der Echoserver zeigt die Zeichenfolgen an. Beachten Sie, wie WLAN- und Stromsperren vor dem Senden erworben werden (und danach natürlich wieder freigegeben werden).
Wenn das Telefon jedoch mit Akku betrieben wird und der Benutzer das Telefon ausschaltet, sendet es für einige Zeit Zeichenfolgen, dann wird das WLAN getrennt und das Telefon reagiert nicht einmal auf Ping. Es dauert 600 bis 6000, bis die Verbindung getrennt ist (die Zahlen sind so rund, daher denke ich, dass sie wichtig sind).
Es funktioniert perfekt, wenn eine Klimaanlage angeschlossen ist, daher denke ich, dass es irgendwie mit der Energieverwaltung zusammenhängt.
Um es zu testen, starte ich einfach die Aktivität, starte den Echo-Server, starte WireShark, drücke den “Start”-Button (android:onClick="doStart"
), blockiert das Telefon und legt es auf den Tisch. Ich gehe zum Mittagessen oder was auch immer und nach 600-6000s kann ich die tx-Fehler auf WireShark sehen, der Echoserver empfängt keinen Datenverkehr mehr und das Telefon reagiert nicht auf Ping.
Das Telefon ist 2.2, mit der WLAN-Richtlinie auf “Schlaf nach 15 m” eingestellt.
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 < 100000; i++) {
ps.println(System.currentTimeMillis() +"("+(new Date()).toString() +") : " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (is.available() > 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();
}
}
}
}
Das Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="Odroid.test"
android:versionCode="1"
android:versionName="1.0"
>
<uses-sdk android:minSdkVersion="4" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
>
<activity
android:name=".Test"
android:label="@string/app_name"
>
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>
Irgendeine Idee?