總結:即使在獲取wifi鎖定時,當手機使用電池時,WiFi會在一段時間後斷開連接。即使有鎖,Wifi睡覺
我已經簡化了問題是單個活動與啓動一個線程的按鈕。它只向PC上運行的回聲服務器發送100.000個字符串(每100ms一個字符串)。見下面的代碼。我可以看到WireShark的流量,並且回顯服務器顯示字符串。注意如何在開始發送之前獲取WiFi和電源鎖(當然,之後發佈)。
然而,當手機電池運行和用戶關閉手機,則會持續發送了一段時間的字符串,然後無線網絡連接斷開,手機甚至不響應Ping。它需要600到6000秒才能斷開(數字是那麼一輪,所以我認爲它們很重要)。
連接的A/C時,它完美的作品,所以我想這是主題相關的電源管理。
爲了測試它,我只需啓動活動,啓動回顯服務器,啓動WireShark,按下「開始」按鈕(android:onClick="doStart"
),封鎖手機並將其放在桌子上。我去吃午餐或任何東西,在600-6000s之後,我可以看到WireShark上的tx錯誤,echo服務器已經停止接收流量,並且電話不響應ping。
的手機是2.2,與「15米後睡眠」設置爲無線網絡政策。
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>
任何想法?
感謝。根據您的鏈接和瀏覽更深入,似乎HTC設備更可能不正確的行爲......這是我的情況(宏達願望)。它聞起來像是問題是在低層次的代碼,可能在HTC WiFi驅動程序等等。 :-(我用一種變通方法 – 2011-03-26 06:59:33
我面臨的HTC Desire HD相同的問題@Jevier請你解釋一下你的解決方法 – Imon 2011-11-22 14:18:55
億盟(對不起,我沒看到到現在爲止評論),很簡單:?如果該設備使用電池,中止執行。對於我的應用程序是可以接受的,但對其他人可能不夠。:-( – 2012-02-03 09:26:59