【问题标题】:GCM high priority messages not received in deep idle mode在深度空闲模式下未收到 GCM 高优先级消息
【发布时间】:2017-02-23 01:03:43
【问题描述】:

进入深度空闲模式后使用:

adb shell dumpsys deviceidle force-idle

我正在尝试按照the documentation 的建议向设备发送高优先级消息,使用:

{ "to" : "feoLl37Ses4:A.......hDQU1OZKd", “优先级”:“高”, “通知” : { "body" : "这是身体。", "title" : "这是标题", “图标”:“新” } }

没有收到消息。 只有在我将设备的状态更改为 IDLE_MAINTENANCE 后才会收到消息。

即使设备处于深度空闲模式,我如何才能让设备接收消息?

【问题讨论】:

  • 您使用的是什么设备?您是否安装了任何可能在手机空闲时杀死谷歌播放服务的任务管理器?
  • 在 HTC 设备上做了一些测试。它没有安装任何任务管理器应用程序。

标签: android google-cloud-messaging


【解决方案1】:

我知道答案很晚,但以防万一有人遇到同样的问题。我遇到了同样的问题,花了几个小时尝试了几个解决方案,直到我得出结论,你不应该使用 adb shell dumpsys deviceidle force-idle 进入深度空闲模式来测试你的推送通知,因为它们根本不会被接收(你的设备除非您执行 unforce 命令,否则无论发生什么都会被强制进入深度空闲模式)。

如果您想在深度空闲模式下测试您的高优先级推送通知,请改用adb shell dumpsys deviceidle step 来完成所有步骤,直到您进入深度空闲模式。这是一个例子。

adb shell dumpsys deviceidle get light
ACTIVE
adb shell dumpsys deviceidle step
Stepped to deep: IDLE_PENDING
adb shell dumpsys deviceidle get light
INACTIVE
adb shell dumpsys deviceidle step
Stepped to deep: SENSING
adb shell dumpsys deviceidle step
Stepped to deep: LOCATING
adb shell dumpsys deviceidle step
Stepped to deep: IDLE
adb shell dumpsys deviceidle get light
OVERRIDE
adb shell dumpsys deviceidle get deep
IDLE

通过这种方式,您将像在真实案例中一样进入深度打盹模式,并且您的推送将按预期收到。 注意,在调用 step 命令之前,您应该执行adb shell dumpsys battery unplug 并关闭设备屏幕。

我的猜测adb shell dumpsys deviceidle force-idle 更强,因为即使设备屏幕打开,它也会强制进入空闲模式。当官方 android doc 说“您可以按照以下步骤测试打盹模式:”并告诉您使用 force-idle 命令时,这完全是误导。因为这种强制空闲不能作为真正的空闲,并且对此没有任何免责声明。

【讨论】:

    【解决方案2】:

    如果您想将应用从打盹状态唤醒(以便您可以接收消息),请使用 setAndAllowWhileIdle()setExactAndAllowWhileIdle()

    当你执行命令时,你的应用进入了打盹模式

    adb shell dumpsys deviceidle force-idle
    

    Doze restrictions

    以下限制适用于您在打瞌睡时的应用:

    1. 网络访问被暂停。
    2. 系统忽略唤醒锁。
    3. 标准 AlarmManager 警报(包括 setExact() 和 setWindow())推迟到下一个维护时段。
    4. 如果您需要设置在打瞌睡时触发的警报,请使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。
    5. 使用 setAlarmClock() 设置的警报继续正常触发 - 系统在这些警报触发前不久退出打盹。
    6. 系统不执行 Wi-Fi 扫描。
    7. 系统不允许同步适配器运行。
    8. 系统不允许 JobScheduler 运行

    对网络访问的 Doze 限制也可能会影响您的应用,尤其是当应用依赖于实时消息时,例如 痒痒或通知。如果您的应用需要持久性 连接到网络以接收消息,您应该使用 Firebase 如果可能,云消息传递 (FCM)。

    为了帮助安排闹钟,Android 6.0(API 级别 23)引入了 两个新的 AlarmManager 方法:setAndAllowWhileIdle() 和 setExactAndAllowWhileIdle()。使用这些方法,您可以设置警报 即使设备处于打瞌睡状态也会触发。

    【讨论】:

      【解决方案3】:

      您必须使用 WakefulBroadcastReceiver,它使用 startWakefulService() 方法来启动执行工作的服务。此方法与 startService() 类似,不同之处在于 WakefulBroadcastReceiver 在服务启动时持有唤醒锁。使用 startWakefulService() 传递的意图包含一个额外的唤醒锁标识。

      第 1 步: 扩展 WakefulBroadcastReceiver 而不是 BroadcastReceiver。

      第 2 步: onReceive() 中的 startWakefulService

      如有任何疑问,请告诉我。

      【讨论】:

      • 我不认为 WakefulBroadcastReceiver 会有所帮助,因为它有助于在接收到广播后保持设备唤醒。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多