I have a service which polls a server at certain intervals. I use an AlarmManager and a BroadcastReceiver to start the service. My problem is that after a certain duration, even though the Wifi is still enabled, but for some reason, my application can't contact the server. I get an "Unreachable network" error.
Note that I've already acquired a partial wake lock as well as a wifilock.
Here's my code for the BroadcastReceiver.
public class ServiceAlarmBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
WakeLock wakeLock = null;
WifiLock wifiLock = null;
try {
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
// acquire a WakeLock to keep the CPU running
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakeLock");
if(!wakeLock.isHeld()){
wakeLock.acquire();
}
Log.i("ServiceAlarmBroadcastReceiver", "WakeLock acquired!");
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL , "MyWifiLock");
if(!wifiLock.isHeld()){
wifiLock.acquire();
}
Log.i("ServiceAlarmBroadcastReceiver", "WifiLock acquired!");
context.startService(new Intent(context, ThePollerService.class));
} finally {
// release the WakeLock to allow CPU to sleep
if (wakeLock != null) {
if (wakeLock.isHeld()) {
wakeLock.release();
Log.i("ServiceAlarmBroadcastReceiver", "WakeLock released!");
}
}
// release the WifiLock
if (wifiLock != null) {
if (wifiLock.isHeld()) {
wif开发者_如何学运维iLock.release();
Log.i("ServiceAlarmBroadcastReceiver", "WiFi Lock released!");
}
}
}
}
}
The problem with the code posted here is that you acquire and release the WakeLock and WifiLock from right inside of your receiver. Unless you are completing your entire task inside of the onStart of your service (which if you are, why even bother having a service???), the locks will be released before your polling task completes.
I would suggest changing your implementation to something like the following:
- Have broadcast receiver start service (and that is all)
- Have service acquire wake locks and kick off the thread to do your polling operation. The most appropriate spot would be your service onCreate)
- After your polled operation is complete, you should stop your polling service
- In the onDestroy of your service, you should release the locks you acquired in onStart
Thanks to Tom, I was able to resolve this issue. Here's the code:
Settings.System.putInt(getContentResolver(),
Settings.System.WIFI_SLEEP_POLICY,
Settings.System.WIFI_SLEEP_POLICY_NEVER);
Under the WiFi Settings, Menu Key, Advanced Options theirs the WIFI_SLEEP_POLICY option list which when set to never will keep the WiFi connection open while the phone is asleep.
You can manipulate this under Settings.System Package.
http://developer.android.com/reference/android/provider/Settings.System.html#WIFI_SLEEP_POLICY
Hope this helps,
Tom
A little edit to javauser's answer:
private void setNeverSleepPolicy() {
try {
ContentResolver cr = getContentResolver();
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
int set = android.provider.Settings.System.WIFI_SLEEP_POLICY_NEVER;
android.provider.Settings.System.putInt(cr, android.provider.Settings.System.WIFI_SLEEP_POLICY, set);
} else {
int set = android.provider.Settings.Global.WIFI_SLEEP_POLICY_NEVER;
android.provider.Settings.System.putInt(cr, android.provider.Settings.Global.WIFI_SLEEP_POLICY, set);
}
} catch (Exception e) {
e.printStackTrace();
}
}
精彩评论