javauser
javauser

Reputation: 225

How do I keep Wifi from disconnecting when phone is asleep?

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()) {
                    wifiLock.release();
                    Log.i("ServiceAlarmBroadcastReceiver", "WiFi Lock released!");
                }
            }
        }
    }
}

Upvotes: 7

Views: 22208

Answers (4)

Arfan Mirza
Arfan Mirza

Reputation: 686

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

Upvotes: 0

Justin Breitfeller
Justin Breitfeller

Reputation: 13801

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:

  1. Have broadcast receiver start service (and that is all)
  2. Have service acquire wake locks and kick off the thread to do your polling operation. The most appropriate spot would be your service onCreate)
  3. After your polled operation is complete, you should stop your polling service
  4. In the onDestroy of your service, you should release the locks you acquired in onStart

Upvotes: 7

javauser
javauser

Reputation: 225

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

Upvotes: 3

iTom
iTom

Reputation: 61

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

Upvotes: 0

Related Questions