代码之家  ›  专栏  ›  技术社区  ›  FCin

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

  •  21
  • FCin  · 技术社区  · 6 年前

    我想在手机锁定时接收来自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命令提示白名单我的应用程序

    我还缺什么?我正在使用三星A5和Android 6.0-API 23。

    我查看了adb命令提示符中的日志,并检查了我的服务实际上是作为前台服务运行的,并且所有锁都被持有。

    1 回复  |  直到 6 年前
        1
  •  5
  •   Barr J    6 年前

    你做的很好,一切都很好。 然而!!

    让我们看看 devleport.android.com 的职位:

    Google Play政策禁止应用程序请求直接豁免 来自Android 6.0+中的电源管理功能(Doze和应用程序待机) 除非应用程序的核心功能受到不利影响。

    你说:

    我正在使用三星A5和Android 6.0-API 23。

    也就是说,当手机进入睡眠状态时,您将无法保持前台服务,因为 应用程序的核心功能是 受到不利影响 .

    这就是为什么你注意到你在手机休眠时停止接收数据包的原因。

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

    编辑: 我现在注意到:

    如果用户将设备拔出并固定一段时间 时间,当屏幕关闭时,设备进入休眠模式。在休眠模式下, 系统试图节约电池 通过限制应用程序访问 网络和CPU密集型服务。它还阻止应用程序 访问网络并推迟其作业、同步和标准 警报。

    打瞌睡限制 :

    • 网络访问被挂起。
    • 系统忽略唤醒锁。
    • 标准AlarmManager警报(包括setExact()和setWindow()) 推迟到下一个维护窗口。
    • 如果你在打盹的时候需要设置警报,使用 setAndallowWhileIdle()或setExactAndallowWhileIdle()。
    • 用setAlarmClock()设置的警报继续正常触发 在警报响起前不久,系统出口会打瞌睡。
    • 系统不执行Wi-Fi扫描。
    • 系统不允许运行同步适配器。
    • 系统不允许运行JobScheduler。

    这将结束我对你所有问题的回答。

    编辑2:

    我进一步调查了一下,在 Xamarin.Android .

    还有一种解决方案,每10分钟唤醒一次手机,以绕过它。 here .