WLAN schläft, auch mit Lock

Lesezeit: 4 Minuten

WLAN schlaft auch mit Lock
Javier Sedano

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?

Es gibt zahlreiche Fehler im Android-Bugtracker, die mit dem WLAN-Schlaf-/Energiesparmodus zu tun haben, und sogar Apps, die versuchen, dies zu beheben. Es ist also sehr wahrscheinlich, dass Sie nichts falsch machen.

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

Schauen Sie sich auch wififixer an, ein Open-Source-Projekt, das Ihnen mit Code helfen kann, um die Verbindung am Leben zu erhalten

http://wififixer.wordpress.com/

  • Danke. Wenn Sie Ihren Links folgen und tiefer stöbern, scheint es, dass sich HTC-Geräte eher falsch verhalten … was bei mir der Fall ist (HTC-Wunsch). Es riecht so, als ob das Problem im Low-Level-Code wäre, vielleicht im HTC WiFi-Treiber oder so. 🙁 Ich habe einen Workaround verwendet.

    – Javier Sedano

    26. März ’11 um 6:59

  • Ich habe das gleiche Problem auf dem HTC Desire HD. @Jevier Würden Sie bitte Ihre Problemumgehung erklären?

    – Imon

    22. November ’11 um 14:18

  • Imon (sorry, ich habe den Kommentar erst jetzt gesehen), ganz einfach: Wenn das Gerät mit Batterien betrieben wird, brechen Sie die Ausführung ab. Es ist für meine Anwendung akzeptabel, für andere jedoch möglicherweise nicht ausreichend. 🙁

    – Javier Sedano

    3. Feb. ’12 um 9:26


.

212450cookie-checkWLAN schläft, auch mit Lock

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy