我想在手机锁定时接收来自 wifi 的数据包。问题是当我锁定屏幕时,我的前台服务停止接收数据包。我正在使用这样的前台服务:
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
var notification = new Notification.Builder(this)
.SetContentTitle(Resources.GetString(Resource.String.app_name))
.SetContentText(Resources.GetString(Resource.String.notification_text))
.SetSmallIcon(Resource.Drawable.ic_stat_name)
.SetContentIntent(BuildIntentToShowMainActivity())
.SetOngoing(true)
.AddAction(BuildRestartTimerAction())
.AddAction(BuildStopServiceAction())
.Build();
// Enlist this instance of the service as a foreground service
StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notification);
/*DO THIS EVEN WHEN SCREEN IS LOCKED*/
var powerManager = (PowerManager)GetSystemService(PowerService);
_wakeLock = powerManager.NewWakeLock(WakeLockFlags.Partial, "WakeLockTag");
_wakeLock.Acquire();
var wifiManager = (WifiManager)GetSystemService(WifiService);
_wifiLock = wifiManager.CreateWifiLock(WifiMode.FullHighPerf, "xamarin_wifi_lock");
_wifiLock.Acquire();
if (!powerManager.IsIgnoringBatteryOptimizations("com.xamarin.xample.foregroundservicedemo") ||
!_wakeLock.IsHeld || !_wifiLock.IsHeld)
throw new InvalidOperationException("OPTIMIZATIONS NOT ACTIVE");
string msg = timestamper.GetFormattedTimestamp();
Log.Debug(TAG, msg);
Intent intent = new Intent(Constants.NOTIFICATION_BROADCAST_ACTION);
intent.SetAction(Android.Provider.Settings.ActionIgnoreBatteryOptimizationSettings);
intent.PutExtra(Constants.BROADCAST_MESSAGE_KEY, msg);
LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
Task.Run(() =>
{
using (var client = new UdpClient(12345))
{
while (true)
{
var result = client.ReceiveAsync().Result;
Console.WriteLine($"RECEIVED: {result.Buffer.Length}");
}
}
});
return StartCommandResult.Sticky;
}
我正在做以下事情来确保它没有被杀死:
- 启动前台服务
- 使用
StartCommandResult.Sticky
- 使用唤醒锁
- 使用 Wifi 锁
- 将 WifiSleepPolicy 设置为
Never
(我在手机中设置了 设置) - 在 Intent 中设置
ActionIgnoreBatteryOptimizationSettings
- 在调试时通过 adb 命令提示符将我的应用列入白名单
我还缺少什么?我正在使用带有 Android 6.0 - API 23 的三星 A5。
我从 adb 命令提示符查看了日志,并检查了我的服务实际上是作为前台服务运行的,并且所有锁都被持有。
最佳答案
你所做的很好,一切都很好。 但是!!
让我们来看看devleport.android.com的帖子:
Google Play policies prohibit apps from requesting direct exemption from Power Management features in Android 6.0+ (Doze and App Standby) unless the core function of the app is adversely affected.
你说:
I am using Samsung A5 with Android 6.0 - API 23.
也就是说,当手机进入休眠状态时,您将无法保持前台服务,因为应用的核心功能 没有 受到不利影响.
这就是您注意到手机处于 sleep 状态时停止接收数据包的原因。
请浏览我附加的整个链接以及我们的 Power Manager指导。
编辑:我现在注意到了:
If a user leaves a device unplugged and stationary for a period of time, with the screen off, the device enters Doze mode. In Doze mode, the system attempts to conserve battery by restricting apps' access to network and CPU-intensive services. It also prevents apps from accessing the network and defers their jobs, syncs, and standard alarms.
打瞌睡限制:
- 网络访问被暂停。
- 系统忽略唤醒锁。
- 标准 AlarmManager 报警(包括 setExact() 和 setWindow()) 推迟到下一个维护时段。
- 如果您需要设置在打瞌睡时触发的警报,请使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。
- 使用 setAlarmClock() 设置的闹钟会继续正常触发 - 系统在警报触发前不久退出打盹。
- 系统不执行 Wi-Fi 扫描。
- 系统不允许同步适配器运行。
- 系统不允许 JobScheduler 运行。
这将结束我对您所有问题的回答。
编辑 2:
我进一步调查了一下,在 Xamarin.Android 中有一篇关于这个问题的完整帖子。 .
还有一个解决方案是每 10 分钟唤醒一次手机以绕过它here .
关于c# - 手机进入休眠状态后,在前台服务中保持 wifi 处于 Activity 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51684502/