Как мне отключить Wi-Fi, когда телефон спит?

У меня есть служба, которая опрашивает сервер через определенные промежутки времени. Я использую AlarmManager и BroadcastReceiver для запуска службы. Моя проблема в том, что через определенное время, хотя Wi-Fi все еще включен, но по какой-то причине мое приложение не может связаться с сервером. Я получаю сообщение об ошибке «Недоступная сеть».

Обратите внимание, что я уже приобрел блокировку частичного следа, а также вайфлок.

Вот мой код для 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!");
                }
            }
        }
    }
}
 CommonsWare06 окт. 2010 г., 13:17
Как вы определили, что проблема в том, что соединение WiFi засыпает. Сообщение «Недоступная сеть» может иметь другие причины. Вы смотрели на широковещательные рассылки или проверили состояние WiFi сWifiManagerили что-нибудь, чтобы подтвердить свою теорию?

Ответы на вопрос(4)

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();
        }
    }
 REJH01 окт. 2015 г., 12:44
Изменение настроек пользователя для этого не рекомендуется. Вы должны подождать с выпуском wake / wifilocks, пока ваши работы не будут закончены.

размещенным здесь, заключается в том, что вы приобретаете и выпускаете WakeLock и WifiLock прямо из вашего ресивера. Если вы не завершите всю свою задачу в рамках запуска службы (что, если вы, зачем вообще беспокоиться о наличии службы ???), блокировки будут сняты до завершения задачи опроса.

Я бы предложил изменить вашу реализацию на что-то вроде следующего:

Иметь услугу запуска приемника вещания (и это все)Попросите службу приобрести блокировочные устройства и начать работу, чтобы выполнить опрос. Наиболее подходящим местом будет ваш сервис onCreate)После завершения опроса вы должны прекратить работу опросаВ onDestroy вашего сервиса вы должны снять блокировки, которые вы приобрели в onStart
 Justin Breitfeller19 нояб. 2011 г., 01:20
Если пользователь отключил Wi-Fi, он не будет переподключен только потому, что вы приобрели блокировку. В противном случае вы можете подождать, пока активная сеть снова не будет подключена, прежде чем пытаться подключиться к вашему сервису. WiFi не должен занять много времени, чтобы быть готовым, так как он не полностью отключен в спящем режиме. На самом деле, я не уверен, что ConnectivityManager даже сообщает, что он не подключен в этой ситуации.
 Paulo Cesar18 нояб. 2011 г., 13:09
Хорошо, давайте предположим, что я объединяюсь каждые 6 часов. С этим интервалом устройство, вероятно, находится в спящем режиме с отключенным Wi-Fi. Когда я запрашиваю WAKE_LOCK для Wi-Fi, на OnStart, он включит Wi-Fi правильно? Но так как Wifi требуется несколько секунд для подключения к точке доступа, неужели моя служба не сможет подключиться к Интернету?
 Paulo Cesar22 нояб. 2011 г., 13:39
Привет Джастин, я думаю, что получил хорошее решение, это зарегистрировать BroadcastReceiver, который определяет, когда было установлено соединение Wi-Fi, а затем проверить, была ли последняя загрузка старше 12 часов (мой интервал пула), и если это так, он загрузит ,

«Клавиша меню», «Дополнительные параметры» представлен список параметров WIFI_SLEEP_POLICY, который, если задано значение «Никогда», не будет поддерживать соединение WiFi открытым, когда телефон спит.

Вы можете управлять этим в Settings.System Package.

http://developer.android.com/reference/android/provider/Settings.System.html#WIFI_SLEEP_POLICY

Надеюсь это поможет,

Том

 javauser06 окт. 2010 г., 17:12
Спасибо за ответ Том. Как вы на самом деле меняете этот параметр?
 REJH01 окт. 2015 г., 12:44
Изменение настроек пользователя для этого не рекомендуется. Вы должны подождать с выпуском wake / wifilocks, пока ваши работы не будут закончены.

Settings.System.putInt(getContentResolver(),
  Settings.System.WIFI_SLEEP_POLICY, 
  Settings.System.WIFI_SLEEP_POLICY_NEVER);
 MZB23 сент. 2014 г., 22:05
Обратите внимание, что это не рекомендуется для API 17. См.stackoverflow.com/a/18790243
 Slavcho31 июл. 2013 г., 11:06
Приведенный выше код требует следующее разрешение: <использование-разрешение android: name = "android.permission.WRITE_SETTINGS" />
 Mr_and_Mrs_D27 апр. 2013 г., 22:49
Это на самом деле выглядит очень плохо - с точки зрения батареи. Как насчет перемещения вашего Wi-Fi блокировки в реализацию вашего сервиса? Является ли ваш сервисWakefulIntentService ? Блокировка от пробуждения, которую вы получаете в приемнике, мало что даст

Ваш ответ на вопрос