Reputation: 343
I am scheduling a notification to be launched when a message is received by the Firebase service but the problem that the notification is triggering twice(once on time and second time after maybe 30 min) here is my code:
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);
This is the 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);
}
And here is Vb.net sending notification Function:
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
is there any better way to send the notification?, is there any problem within the AlarmManager? Thank you.
Upvotes: 0
Views: 1295
Reputation: 3016
Return START_NOT_STICKY from MyAlarmService.onStartCommand() instead of calling the super method. The super method returns START_STICKY, which will restart your service after it gets killed by the system, re-triggering the notification.
The other question is whether using a service for this is a good idea in general. I'd try a BroadcastReceiver, that won't keep running after you're done.
Upvotes: 1
Reputation: 344
Your code seems to be Ok. But according to the documentation:
A common scenario for triggering an operation outside the lifetime of your app is syncing data with a server. This is a case where you might be tempted to use a repeating alarm. But if you own the server that is hosting your app's data, using Google Cloud Messaging (GCM) in conjunction with sync adapter is a better solution than AlarmManager. A sync adapter gives you all the same scheduling options as AlarmManager, but it offers you significantly more flexibility. For example, a sync could be based on a "new data" message from the server/device (see Running a Sync Adapter for details), the user's activity (or inactivity), the time of day, and so on. See the linked videos at the top of this page for a detailed discussion of when and how to use GCM and sync adapter.
Source: Scheduling Repeating Alarms documentation
Maybe you could try using the Sync adapter. Also check if you are receiving the notification twice (I think you are not). Or check if the Alarm is set to a repeting period of 30mins.
Hope this helps.
Upvotes: 1