Я перенес свой проект с GCM на Firebase. Push-уведомление приходит нормально, когда устройство не спит или недавно спало, но если я оставлю устройство, скажем, на час, push-уведомление не будет отправлено, пока я не разбуду устройство.
В документах Android говорится, что если вам нужно разбудить устройство для доставки сообщения, используйте FireBase с высоким приоритетом. В нем также говорится, что приложения администратора устройства не подпадают под ограничения Doze, мое приложение является приложением администратора устройства.
Я подумал, что упомяну, что при переносе проекта с 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 года.
Приложения для администрирования устройства не подпадают под действие Doze, мое - это приложение для администрирования устройства, но я также явно добавил приложение в белый список Doze, который можно найти в разделе «Настройки» -> «Батарея» -> «Оптимизация». Это было сделано вручную через приложение настроек, а НЕ программно в коде.
Я оставил свое устройство спать на 3 часа, и ничего не происходит. Я также использовал adb, чтобы перевести устройство в режим Doze. Когда adb переводит устройство в режим Doze, толчок не принимается, когда adb выводит устройство из режима Doze, толчок проходит.
другие мысли, которые я не пробовал.
Мои толчки - это сообщения с данными. Это потому, что я не хочу, чтобы push приходил на панель уведомлений на устройстве и чтобы пользователь щелкнул его, чтобы выполнить функцию. Пользователь не взаимодействует с приложением администратора устройства. Таким образом, сообщение с данными обрабатывается
onMessageReceived(RemoteMessage remoteMessage)
Я считаю, что сообщения с уведомлениями вызывают пробуждение устройства, что мне и нужно, но я хочу, чтобы приложение обрабатывало push, а не пользователь. Могу ли я иметь сообщения, которые являются одновременно уведомлением и данными, но с функцией onMessageRecievied для обработки этих функций?
Кто-нибудь испытывал что-либо подобное или есть какие-либо решения для этого?
[EDIT1] Я нашел следующую ссылку ниже, в которой говорится, что вы можете отправить сообщение, которое является одновременно уведомлением и данными, но если приложение находится в фоновом режиме, уведомление отображается, но данные выполняются только тогда, когда пользователь щелкает уведомление. Это не то, что я хочу, так как я хотел бы, чтобы данные сразу выполнялись в onMessageRecived.
[EDIT2] Я добавил в приложение следующий код и разрешение. Теперь приложение просит пользователя внести приложение в белый список для Doze, поэтому я нажал кнопку «Да». Затем я через adb поместил устройство в режим Doze и отправил push. Ничего не происходило, пока я не вывел устройство из спящего режима. Так что, к сожалению, это не работает.
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]
Я провел дополнительное тестирование, чтобы попытаться изолировать проблему и исключить код моего веб-приложения из уравнения. Я поместил устройство в Doze через adb и используемую консоль FireBase, чтобы вместо этого отправить push. Отправка прошла правильно. Это говорит мне о проблеме с кодом моего веб-приложения, который отправляет всю информацию push на конечную точку fcm. Я получу код сегодня вечером и отправлю его позже.
[EDIT4] Я только что провел еще несколько тестов. Я поместил устройство в дремоту, а затем использовал консоль FireBase для отправки сообщения с данными с двумя парами ключ-значение. Когда устройство находится в дремоте, а приложение находится на переднем плане (на экране), проталкивание проходит и выполняется onMessageReceived. Отлично. Однако, если приложение находится в BG, отображается только уведомление. Я понимаю, что из документации сообщения данных отправляются в действие средства запуска через намерение, но мое приложение запуска не обрабатывает нажатия. Класс, который обрабатывает нажатия, называется MyAndroidFirebaseMsgService и расширяет FirebaseMessagingService.
Должен ли я направлять намерение в этот класс, если приложение находится в BG? Кажется, это немного страдает. В GCM этого никогда не было.
Кроме того, я не хочу, чтобы приложение запускалось из push-уведомлений, поскольку это очень агрессивно, поскольку пользователь устройства может использовать другое приложение. Мое приложение также является приложением для администрирования устройства, поэтому в 99% случаев взаимодействие с пользователем отсутствует, это просто клиент, который выполняет политики на устройстве.
[edit5]
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)
{
}
}//
Благодарность
onMessageReceived
. Вы получили этот обратный звонок? - person Eugen Pechanec   schedule 30.01.2018