How to show a notification everyday at a certain time even when the app is closed?

Hussein El Feky picture Hussein El Feky · Oct 10, 2015 · Viewed 17.5k times · Source

Although this question might have been asked before on Stack Overflow, I still haven't found a clear answer.

I want to show a notification everyday at 12pm for example even when the app is closed. I have referenced from those links: Notifications in specific time every day android, Android daily repeating notification at specific time of a day using AlarmManager, Android BroadcastReceiver on startup - keep running when Activity is in Background and much more... I'm confused on the difference between Service and BroadcastReceiver. Which one shall I use? or shall I use both of them?

So far, I know how to show a notification, but I don't know how to show it automatically once everyday even when the app is closed.

My code:

public class NotifyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Service created", Toast.LENGTH_LONG).show();

        Intent resultIntent = new Intent(this, HomeScreen.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, 0);

        Notification.Builder notification = new Notification.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("App Title")
                .setContentText("Some Text...")
                .setContentIntent(resultPendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT < 16) {
            notificationManager.notify(1, notification.getNotification());
        } else {
            notificationManager.notify(1, notification.build());
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service destroyed", Toast.LENGTH_LONG).show();
    }
}

AppManifest.xml:

<service android:name=".NotifyService" />

How should I write my code to accomplish what I want? Any suggestions or any good link that I can understand from?

Answer

Jimale Abdi picture Jimale Abdi · Apr 29, 2019

This is updated solution, and it works Android Oreo

Step 1: Create a Method in your MainActivity and use AlarmManager to set alarm at a specified time.

public void myAlarm() {
  
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 21);
    calendar.set(Calendar.MINUTE, 47);
    calendar.set(Calendar.SECOND, 0);
    
    if (calendar.getTime().compareTo(new Date()) < 0) 
        calendar.add(Calendar.DAY_OF_MONTH, 1);

    Intent intent = new Intent(getApplicationContext(), NotificationReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    
    if (alarmManager != null) {
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);

  }
  
}

I'm setting my alarm at 09:47 PM

Step 2: Create BroadcastReceiver to listen when the alarm happens

public class NotificationReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    NotificationHelper notificationHelper = new NotificationHelper(context);
    notificationHelper.createNotification();

   }
}

I'm creating this class named NotificationReceiver and extends BroadcastReceiver, in onReceive there is Class named NotificationHelper, don't confuse I will explain this Class for next steps.

Step 3: Create the Notification class

class NotificationHelper {

private Context mContext;
private static final String NOTIFICATION_CHANNEL_ID = "10001";

NotificationHelper(Context context) {
    mContext = context;
}

void createNotification()
{
   
    Intent intent = new Intent(mContext , NotificationActivity.class);
   
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent resultPendingIntent = PendingIntent.getActivity(mContext,
            0 /* Request code */, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);


    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID);
    mBuilder.setSmallIcon(R.mipmap.ic_launcher);
    mBuilder.setContentTitle("Title")
            .setContentText("Content")
            .setAutoCancel(false)
            .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
            .setContentIntent(resultPendingIntent);

    NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
    {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.RED);
        notificationChannel.enableVibration(true);
        notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
        assert mNotificationManager != null;
        mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        mNotificationManager.createNotificationChannel(notificationChannel);
    }
    assert mNotificationManager != null;
    mNotificationManager.notify(0 /* Request Code */, mBuilder.build());
       }
     }

This class handles the notification

Step 4: Come back to Step 2: and call the Notification Class

 NotificationHelper notificationHelper = new NotificationHelper(context);
 notificationHelper.createNotification();

Registering a BroadcastReceiver Go to your Androidmanifest file and register your broadcast receiver

<receiver
    android:name=".NotificationReceiver"></receiver>

For more info refer this guide from google

I hope it helps you.