c# - 手机进入休眠状态后,在前台服务中保持 wifi 处于 Activity 状态

标签 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. 在 Intent 中设置 ActionIgnoreBatteryOptimizationSettings
  7. 在调试时通过 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/

相关文章:

ios - 将文件从 iOS 应用程序扩展保存到包含的应用程序

c# - 使用 NLog 在 ASP.NET Core 中记录异常

c# - 如何正确使用.NET2.0串口.BaseStream进行异步操作

c# - 在 Visual Studio 2010 中使用目标构建时收到大量警告

c# - 将 lambda 字符串表达式转换为 Func<string, string> 错误 : "No property or field ' v' exists in type 'String' "

java - Android Studio 更新位置时位置标记消失

php - 带有换行符示例的 Android SAX 解析器?

java - Spinner 获取其项目值(而不是位置)

android - 在 GridView 适配器 GetView 方法中使用异步方法

android - 设置背景后按钮变大 - 如何使其变小