如何在应用程序处于后台时每 10 分钟处理一次从 Firebase 收到的 onNotificationReceived。 Android 9.0
How to handle onNotificationReceived from Firebase every 10 minutes while app is in background. Android 9.0
每次收到来自 Firebase 的静默推送通知时,我都需要能够将我的 GPS 位置发送到服务器。发送通知的计时器当前设置为每 10 分钟一次。当 phone 充电时这不是问题,但当它空闲且应用程序在后台时,FirebaseMessagingService 的 onMessageReceived 仅每隔几个小时调用一次。这让我相信它与 Android 9.0 的新电源管理规则有关。但是为了让我的应用程序正常工作,我需要能够每 10 分钟发送一次我的位置。不只是有时候。
我尝试使用 Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
将电池优化设置为 'not optimised'
这个好像没什么效果
我还尝试将 Firebase 通知的优先级设置为高。这有效,但每天只能发送 10 条消息,这意味着它不是我的应用程序的解决方案。 (Source: Power Management restrictions)
我现在试图通过打开一个 foregroundService 来始终将应用程序放在 'Active' 存储桶中。这应该确保应用程序永远不会在任何其他桶中,通知可以延迟几个小时。
An app is in the active bucket if the user is currently using the app, for example:
- The app has launched an activity
- The app is running a foreground service
- The app has a sync adapter associated with a content provider used by a foreground app
- The user clicks on a notification from the app
If an app is in the active bucket, the system does not place any restrictions on the app's jobs, alarms, or FCM messages.
(Source: Power Buckets Android9).
不过,这似乎不是我想要的解决方案,因为它可能不是最佳实践。而且它似乎也不管用。
这是我的 onMessageReceived 函数:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
PushNotificationManager.getInstance().handlePushNotification(object, getApplicationContext());
}
}
现在我不知道为什么Firebase消息没有进入onMessageReceived函数。
蒂姆,
我认为主要问题在于您如何发送推送通知及其内容。
如果你在这里检查 - https://firebase.google.com/docs/cloud-messaging/android/receive
您会看到,如果消息包含通知数据并且应用程序处于后台,则推送通知会转到通知区域。
您需要发送仅包含数据的推送通知:
(在这里您可以找到有关不同类型的更多信息 - https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages)
这是如何触发它的解释 -
在 Cloud Functions 或您的应用服务器等受信任的环境中,使用 Admin SDK 或 FCM 服务器协议:仅设置数据密钥。
请注意,如果您需要执行较长的 运行 操作,那么您将需要启动一个单独的服务(该服务应在通知区域显示一个通知,它是 运行 ,否则你会在较新的 Android 版本上崩溃)
已使用 AlarmManager 修复。在 10 分钟后安排一个闹钟,并在完成闹钟内的代码后,在 10 分钟后安排一个新闹钟。
如果 AlarmManager 处于休眠模式,它可以唤醒 phone,这意味着触发器中的所有代码都将正常执行。
每次收到来自 Firebase 的静默推送通知时,我都需要能够将我的 GPS 位置发送到服务器。发送通知的计时器当前设置为每 10 分钟一次。当 phone 充电时这不是问题,但当它空闲且应用程序在后台时,FirebaseMessagingService 的 onMessageReceived 仅每隔几个小时调用一次。这让我相信它与 Android 9.0 的新电源管理规则有关。但是为了让我的应用程序正常工作,我需要能够每 10 分钟发送一次我的位置。不只是有时候。
我尝试使用 Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
将电池优化设置为 'not optimised'
这个好像没什么效果
我还尝试将 Firebase 通知的优先级设置为高。这有效,但每天只能发送 10 条消息,这意味着它不是我的应用程序的解决方案。 (Source: Power Management restrictions)
我现在试图通过打开一个 foregroundService 来始终将应用程序放在 'Active' 存储桶中。这应该确保应用程序永远不会在任何其他桶中,通知可以延迟几个小时。
An app is in the active bucket if the user is currently using the app, for example:
- The app has launched an activity
- The app is running a foreground service
- The app has a sync adapter associated with a content provider used by a foreground app
- The user clicks on a notification from the app
If an app is in the active bucket, the system does not place any restrictions on the app's jobs, alarms, or FCM messages.
(Source: Power Buckets Android9).
不过,这似乎不是我想要的解决方案,因为它可能不是最佳实践。而且它似乎也不管用。
这是我的 onMessageReceived 函数:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
PushNotificationManager.getInstance().handlePushNotification(object, getApplicationContext());
}
}
现在我不知道为什么Firebase消息没有进入onMessageReceived函数。
蒂姆, 我认为主要问题在于您如何发送推送通知及其内容。 如果你在这里检查 - https://firebase.google.com/docs/cloud-messaging/android/receive 您会看到,如果消息包含通知数据并且应用程序处于后台,则推送通知会转到通知区域。 您需要发送仅包含数据的推送通知: (在这里您可以找到有关不同类型的更多信息 - https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages) 这是如何触发它的解释 - 在 Cloud Functions 或您的应用服务器等受信任的环境中,使用 Admin SDK 或 FCM 服务器协议:仅设置数据密钥。
请注意,如果您需要执行较长的 运行 操作,那么您将需要启动一个单独的服务(该服务应在通知区域显示一个通知,它是 运行 ,否则你会在较新的 Android 版本上崩溃)
已使用 AlarmManager 修复。在 10 分钟后安排一个闹钟,并在完成闹钟内的代码后,在 10 分钟后安排一个新闹钟。
如果 AlarmManager 处于休眠模式,它可以唤醒 phone,这意味着触发器中的所有代码都将正常执行。