Подтвердить что ты не робот

Wifi спит, даже с Lock

Резюме: даже когда Wi-Fi блокируется, когда телефон работает от батарей, Wi-Fi отключается через некоторое время.

Я упростил проблему до одного действия с помощью кнопки, запускающей поток. Он просто отправляет 100 000 строк на эхо-сервер, работающий на ПК (одна строка каждые 100 мс). См. Код ниже. Я вижу трафик с помощью WireShark, а также на эхо-сервере отображаются строки. Обратите внимание на то, что Wi-Fi и блокировки питания были приобретены до начала отправки (и, конечно, после освобождения).

Однако, когда телефон работает от батареи, и пользователь выключает телефон, он продолжает отправлять строки в течение некоторого времени, а затем отключается Wi-Fi и телефон даже не отвечает на ping. Требуется от 600 до 6000 секунд для отключения (цифры округлены, поэтому я думаю, что они важны).

Он отлично работает, когда подключен A/C, поэтому я думаю, что это как-то связано с управлением питанием.

Чтобы проверить это, я просто запускаю действие, запускаю эхо-сервер, запускаю WireShark, нажимаю кнопку "Пуск" (android:onClick="doStart"), блокирует телефон и оставляю его на столе. Я иду на обед или что-то еще, и после 600-6000 я вижу ошибки tx на WireShark, эхо-сервер прекратил получать трафик, и телефон не отвечает на ping.

Телефон равен 2,2, а политика Wi-Fi установлена ​​на "sleep after 15m".

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

манифест:

<?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>

Любая идея?

4b9b3361

Ответ 1

Есть множество ошибок в Android-отладчике ошибок, связанных со спящим/энергосберегающим режимом WiFi и даже с доступными приложениями, которые пытаются исправить это. Поэтому вполне вероятно, что вы не делаете ничего плохого.

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

Также проверьте wififixer, который является проектом с открытым исходным кодом, который может помочь вам с кодом, чтобы поддерживать связь в режиме

http://wififixer.wordpress.com/