我正计划在Firebase服务收到消息时启动通知,但是通知触发两次(一次准时,第二次可能是30分钟后)的问题是我的代码:
sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Intent myIntent = new Intent(MyFirebaseMessagingService.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(MyFirebaseMessagingService.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
long currentTime = System.currentTimeMillis();
int hour=sharedPreferences.getInt("Hour",9);
int min=sharedPreferences.getInt("Min",0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,hour);
calendar.set(Calendar.MINUTE,min);
alarmManager.set(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , pendingIntent);
这是MyAlarmService onStartCommand:
public int onStartCommand(Intent intent, int flags, int startId) {
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(R.mipmap.ic_launcher);
mBuilder.setContentTitle("Figures");
mBuilder.setContentText("New Figures has been updated!");
mBuilder.setAutoCancel(true);
mBuilder.setSound(uri);
Intent resultIntent = new Intent(this, LoginActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(LoginActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
return super.onStartCommand(intent, flags, startId);
}
这是Vb.net发送通知功能:
Private Function sendNotification() As Integer
Try
Dim url As String = "https://fcm.googleapis.com/fcm/send"
Dim tRequest As WebRequest = WebRequest.Create(url)
tRequest.Method = "post"
tRequest.ContentType = "application/json"
Dim data = New With { _
Key .[to] =myTopic, _
Key .TTL = "109", _
Key .data = New With { _
Key .body = "Updated", _
Key .title = "Daily" _
} _
}
Dim jssons As String = Newtonsoft.Json.JsonConvert.SerializeObject(data)
Dim bytearray As Byte() = Encoding.UTF8.GetBytes(jssons)
tRequest.Headers.Add(String.Format("Authorization: key={0}", MyKey))
tRequest.Headers.Add(String.Format("Sender: id={0}", MySenderId))
tRequest.ContentLength = bytearray.Length
tRequest.ContentType = "application/json"
Using datastream As Stream = tRequest.GetRequestStream()
datastream.Write(bytearray, 0, bytearray.Length)
Using tresponse As WebResponse = tRequest.GetResponse
Using dataStreamResponse As Stream = tresponse.GetResponseStream()
Using tReader As StreamReader = New StreamReader(dataStreamResponse)
Dim sResponseFromServer As String = tReader.ReadToEnd()
Log(sResponseFromServer, w)
End Using
End Using
End Using
End Using
Catch ex As WebException
Log(ex.Message, w)
Return ex.Status
End Try
Log("Notification sent", w)
Return 200
End Function
有没有更好的方式发送通知?,AlarmManager中有任何问题吗? 谢谢。
答案 0 :(得分:1)
您的代码似乎没问题。但根据文件:
在应用的生命周期之外触发操作的常见方案是与服务器同步数据。在这种情况下,您可能会想要使用重复警报。但是,如果您拥有托管应用程序数据的服务器,则将Google云消息传递(GCM)与同步适配器结合使用是比AlarmManager更好的解决方案。同步适配器为您提供与AlarmManager相同的调度选项,但它为您提供了更大的灵活性。例如,同步可以基于"新数据"来自服务器/设备的消息(有关详细信息,请参阅运行同步适配器),用户的活动(或不活动),一天中的时间等。有关何时以及如何使用GCM和同步适配器的详细讨论,请参阅本页顶部的链接视频。
来源:Scheduling Repeating Alarms documentation
也许您可以尝试使用同步适配器。还要检查您是否收到了两次通知(我认为您不是)。或者检查警报是否设置为30分钟的重复周期。
希望这有帮助。
答案 1 :(得分:1)
从MyAlarmService.onStartCommand()返回START_NOT_STICKY,而不是调用super方法。 super方法返回START_STICKY,它会在系统被系统杀死后重启你的服务,重新触发通知。
另一个问题是,使用服务是否是一个好主意。我会尝试一个BroadcastReceiver,在你完成后不会继续运行。