Im trying to create a part of a fitness application that will remind a user to do their daily exercises at a chosen time. This is utilising the AlarmManager to create a daily alarm which will create a notification that will appear at the chosen time.
When the alarm time comes, no notification comes through. I've tested the notification, and it will appear if placed on the action click of a button.
Should I be using extends BroadcastReceiver instead of extends Service?
Creating the alarm:
public void SaveAlarm(View V) {
Intent myIntent = new Intent(SetAlarm.this, NotifyService.class);
AlarmManager mAlarmManager = (AlarmManager) this.getSystemService(ALARM_SERVICE);
mPendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
//Create Alarm Time in calendar
Calendar mCalendar = Calendar.getInstance();
mCalendar.setTimeInMillis(System.currentTimeMillis());
mCalendar.set(Calendar.HOUR_OF_DAY, AlarmHour);
mCalendar.set(Calendar.MINUTE, AlarmMinute);
//Set alarm to repeat ever 24hrs
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, mPendingIntent);
//Save Alarm to shared preferences
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("AlarmHour", AlarmHour);
editor.putInt("AlarmMinute", AlarmMinute);
editor.commit();
//Notify user it's been saved
Toast.makeText(this, "Alarm Saved", Toast.LENGTH_LONG).show();
//Switch view
Intent intent = new Intent(SetAlarm.this, Home.class);
startActivity(intent);
}
Class to create notification:
public class NotifyService extends Service {
@Override
public IBinder onBind(Intent Intent) {
return null;
}
@Override
public void onCreate() {
createNotificationChannel();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "Workout")
.setSmallIcon(R.drawable.common_google_signin_btn_text_light)
.setContentTitle("Workout Time!")
.setContentText("Time to do your daily workout.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
notificationManager.notify(1, builder.build());
}
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Workout";
String description = "Workout";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("Workout", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}
According to official Android docs of Service
component:
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.
In your case, triggering a simple notification is not considered a long-running operation, so you should use BroadcastReceiver
which is designed to run for a simple task at a specific conditions.
To implement this using a BroadcastReceiver
you should first change your service to a BroadcastReceiver
:
public class NotifyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Notify user here
}
}
Then pass your receiver to AlarmManager
like this:
public void SaveAlarm(View V) {
Intent myIntent = new Intent(SetAlarm.this, NotifyReceiver.class);
AlarmManager mAlarmManager = (AlarmManager) this.getSystemService(ALARM_SERVICE);
mPendingIntent = PendingIntent.getBroadcast(SetAlarm.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
...
}
Don't forget to declare your receiver in AndroidManifest.xml
:
<receiver android:name=".NotifyReceiver"/>