我有一个服务,以一定的间隔轮询服务器。 我使用AlarmManager和BroadcastReceiver来启动服务。 我的问题是,经过一段时间后,即使Wifi仍然启用,但由于某种原因,我的应用程序无法联系服务器。 我收到“无法访问的网络”错误。
请注意,我已经获得了部分唤醒锁以及wifilock。
这是我的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!"); } } } } }
这里发布的代码的问题是您从接收器内部获取并释放WakeLock和WifiLock。 除非你在服务的onStart中完成你的整个任务(如果你是这样,为什么甚至打扰服务???),锁定将在你的轮询任务完成之前被释放。
我建议将您的实现更改为以下内容:
有广播接收器启动服务(这就是全部)
服务获取唤醒锁定并启动线程以执行轮询操作。 最合适的地方是你的服务onCreate)
轮询操作完成后,您应该停止轮询服务
在服务的onDestroy中,您应该释放在onStart中获取的锁
感谢Tom,我能够解决这个问题。 这是代码:
Settings.System.putInt(getContentResolver(), Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_NEVER);
在WiFi设置,菜单键,高级选项下,它们是WIFI_SLEEP_POLICY选项列表,当设置为永不会在手机处于睡眠状态时保持WiFi连接打开。
您可以在Settings.System Package下操作它。
希望这可以帮助,
汤姆
对javauser的答案进行一点编辑:
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(); } }