【发布时间】:2018-07-05 05:26:29
【问题描述】:
我已将我的项目从使用 GCM 迁移到使用 Firebase。当设备最近处于唤醒或睡眠状态时,推送通知正常,但如果我离开设备一个小时,则在唤醒设备之前不会发送任何推送。
Android 文档说,如果您需要唤醒设备来传递消息,请使用 FireBase,并将优先级设置为高。它还说设备管理应用不受打盹限制,我的应用是设备管理应用。
我想我会提到,当我将项目从 GCM 迁移到 FCM 时,我只在 firebase 控制台中指定了包名,而不是指纹。
我已经尝试过了。
-
将优先级设置为高
{ "time_to_live": 300000, "delay_while_idle": false, "android": { "priority": "high" }, "data": { "message": "PING_DEVICE", "time": "21/01/2018 16:20:28", "pushguid": "10062" }, "registration_ids": [ "eOMT........" ] }设定了生存时间,因此消息最终会通过。 delay_while_idle 设置为 false,FCM 会在 2016 年 9 月后忽略它。
设备管理应用不受 Doze 约束,我的是设备管理应用,但我还明确将该应用添加到设置 -> 电池 -> 优化中的 Doze 白名单中。这是通过设置应用手动完成的,而不是在代码中以编程方式完成。
我已经让我的设备进入睡眠状态 3 小时,并且没有任何推动。我还使用 adb 将设备放入 Doze。当 adb 将设备置于 Doze 时没有收到推送,当 adb 将设备从 Doze 中取出时,推送通过。
我没有尝试过的其他想法。
我的推送是数据消息。这是因为我不希望推送到达设备上的通知栏并让用户单击它来执行功能。用户与设备管理应用程序没有交互。所以一条数据消息由
处理onMessageReceived(RemoteMessage remoteMessage)
我相信通知消息确实会唤醒设备,这是我需要的,但我希望应用程序而不是用户来处理推送。我能否拥有既是通知又是数据但让 onMessageRecievied 处理功能的消息?
有没有人遇到过类似的情况或有解决办法?
[编辑1] 我发现下面的链接说您可以发送既是通知又是数据的消息,但是如果应用程序在后台,则会显示通知,但仅在用户单击通知时才会执行数据。这不是我想要的,因为我希望数据立即在 onMessageRecived 中执行。
[编辑2] 我已向应用程序添加以下代码和权限。该应用程序现在要求用户将该应用程序列入 Doze 应用程序的白名单,因此我单击“是”。然后我通过 adb 将设备置于 Doze 状态并发送推送。直到我将设备退出打盹模式之前,什么都没有发生。所以,不幸的是,这不起作用。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
[编辑3]
我已经进行了进一步的测试,试图找出问题所在,并将我的 Web 应用程序代码排除在外。我通过 adb 将设备放入 Doze 并使用 FireBase 控制台来发送推送。 推送正确完成这告诉我,我的 Web 应用程序代码存在问题,该代码将所有推送信息发送到 fcm 端点。今晚我会得到代码并稍后发布。
[编辑4] 我刚刚做了一些测试。我将设备置于打盹状态,然后使用 FireBase 控制台发送带有 2 个键值对的数据消息。当设备处于打盹且应用程序处于前台(屏幕上)时,推送将通过并执行 onMessageReceived。这很棒。但是,如果应用程序位于 BG 中,则只会显示通知。我从文档中了解到,数据消息通过 Intent 发送到启动器活动,但我的启动器应用程序不处理推送。处理推送的类称为 MyAndroidFirebaseMsgService 并扩展 FirebaseMessagingService。
如果应用程序位于 BG 中,我是否必须将意图路由到此类?似乎有点starnge必须这样做。在 GCM 中从未出现过这种情况。
另外,我不希望应用程序从推送中启动,因为这是非常具有侵入性的,因为设备用户可能正在使用不同的应用程序。我的应用也是一个设备管理应用,所以 99% 的时间没有用户交互,它只是一个在设备上执行策略的客户端。
[编辑5]
internal static void SendNotification ( Dictionary<string, string> nameValues , List<string> theregIDs , string sPushName)
{
string stringregIds = string.Join("\",\"", theregIDs) ;
JavaScriptSerializer js = new JavaScriptSerializer();
string keyValueJson = js.Serialize(nameValues);
string TIME_TO_LIVE = "604800";
string DELAY_WHILE_IDLE = "false";
string ENDPOINTADDRESS = @"https://fcm.googleapis.com/fcm/send";
postData = String.Concat("{\"time_to_live\":", TIME_TO_LIVE, ",\"delay_while_idle\": ", DELAY_WHILE_IDLE, ", \"android\":{\"priority\":\"high\" } ,\"data\": { \"message\" : " + "\"" + sPushName + "\",\"time\": " + "\"" + System.DateTime.Now.ToString() + "\""
, keyValueJson
, "},\"registration_ids\":[\"" + stringregIds + "\"]}");
WebRequest myWebRequest = null;
WebResponse myWebResponse = null;
try
{
myWebRequest = WebRequest.Create(ENDPOINTADDRESS);
myWebRequest.Method = "post";
myWebRequest.ContentType = "application/json";
// myWebRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
myWebRequest.Headers.Add("Authorization: key=" + Our_Api_Key);
myWebRequest.Headers.Add("Sender:id=" + Our_Sender_Id);
Byte[] BA = Encoding.UTF8.GetBytes(postData);
myWebRequest.ContentLength = BA.Length;
using (Stream dataStreamOut = myWebRequest.GetRequestStream())
{
dataStreamOut.Write(BA, 0, BA.Length);
}
using (myWebResponse = myWebRequest.GetResponse())
{
using (Stream dataStream = myWebResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStream))
{
strServerResponse = tReader.ReadToEnd();
}
}
}
}
catch (WebException ex)
{
}
}//
谢谢
【问题讨论】:
-
它是否适用于较低的android版本,你在哪里添加优先级和数据?
-
@PeterHaddad 嗨,我还没有在较低的 Android 版本上测试过它。我将采购的所有手机都是 Android 6+。我会要求我的业务伙伴给我一个代码 sn-p,说明他如何将数据发送到 FCM 端点。我应该设置优先级和数据的特殊位置或顺序吗?
-
关于您的 EDIT3,Firebase 控制台只允许发送推送 通知(据我记忆)。这些由 Google Play 服务处理如果您的应用程序未运行,它会代表您发布通知。它不会启动您的应用程序,您也不会收到
onMessageReceived回调。你收到那个回调了吗? -
@EugenPechanec 啊,你说得对,它只是一条通知消息,没有产生回调。您对问题可能是什么有任何进一步的想法?
-
你找到解决办法了吗?
标签: android firebase-cloud-messaging device-admin