手机进入睡眠状态后,保持wifi在前台服务中处于活动状态

时间:2018-08-04 10:04:05

标签: c# android xamarin xamarin.forms xamarin.android

我想在手机锁定时从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;
}

我正在做以下事情以确保它没有被杀死:

  1. 开始前台服务
  2. 使用StartCommandResult.Sticky
  3. 使用唤醒锁
  4. 使用Wifi锁
  5. 将WifiSleepPolicy设置为Never(我已经在手机中对其进行了设置 设置)
  6. 设置ActionIgnoreBatteryOptimizationSettings意图
  7. 在调试时通过adb命令提示符将我的应用列入白名单

我还想念什么?我正在将Samsung A5与Android 6.0-API 23配合使用。

我从adb命令提示符下查看了日志,并检查了我的服务是否实际上已作为Foreground Service运行并且所有锁都已保留。

1 个答案:

答案 0 :(得分:5)

您正在做的事情很棒,一切都很好。 但是!

让我们看看devleport.android.com的帖子:

  

Google Play政策禁止应用请求直接豁免   从Android 6.0+(打ze和App Standby)中的电源管理功能获得   除非该应用的核心功能受到不利影响。

您说:

  

我正在将Samsung A5与Android 6.0-API 23配合使用。

这意味着,手机进入睡眠状态后,您将无法保留前台服务,因为该应用的核心功能 受到了不利影响

这就是为什么您发现您在电话休眠时停止接收数据包的原因。

请浏览我附加的整个链接,以及我们的Power Manager指南。

编辑:我现在进一步注意到:

  

如果用户在一段时间内未插拔设备并保持静止   时间,屏幕关闭时,设备进入打ze模式。在打ze模式下,   系统尝试通过限制应用访问以下内容来节省电池   网络和CPU密集型服务。它还会阻止应用   访问网络并推迟其工作,同步和标准   警报。

打ze限制

  • 网络访问已暂停。
  • 系统忽略唤醒锁。
  • 标准AlarmManager警报(包括setExact()和setWindow()) 推迟到下一个维护窗口。
  • 如果您需要设置在打ze睡时触发的警报,请使用 setAndAllowWhileIdle()或setExactAndAllowWhileIdle()。
  • 使用setAlarmClock()设置的警报继续正常触发- 警报发出前不久,系统退出Doze。
  • 系统不执行Wi-Fi扫描。
  • 系统不允许运行同步适配器。
  • 系统不允许JobScheduler运行。

这将结束我对您所有查询的回答。

编辑2:

我作了进一步调查,Xamarin.Android中有关于此问题的整篇文章。

还有一种解决方案,每隔10分钟唤醒电话以绕过here