How to Show Daily Offline Notifications in Android 10

How to show daily offline notifications in Android 10?

I can see one possible issue, and it's possible to do this without the workmanager (assuming the device has a healthy connection at the time the notification runs).

Instead of doing your network in the receiver itself, I suggest starting a service (foreground service if above Android 8.0), and doing your work there. This is because android's time limit for a receiver is much lower than a service/foreground service. So to me, it sounds plausible that your receiver is killed before the network request completes, and so no notification is shown.

You can show the notification in the service, and also schedule the next alarm since setExactAndAllowWhileIdle isn't a repetitive alarm on it's own. So in your receiver, something like:

@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, BirthdayNotifyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(service);
} else {
context.startService(service);
}
}

Then a possible service class:

public class BirthdayNotifyService extends IntentService {

public BirthdayNotifyService() {
super("BirthdayNotifyService");
}

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Build a simple notification to show if a foreground service is neccesary
Notification noti = notiBuilder.build();
startForeground(1, noti);
}

//Do your network request work here. After completed, show your birthday notification and stop the foreground service.
}
}

To stop the service, right AFTER you display your notification for birthdays, use the following:

stopForeground(true);
stopSelf();

UPDATE: I used this method on my phone (Xiaomi Redmi Note 8 plus), it worked a few times but then stopped working. It works perfectly fine on stock android, but not on all devices. Therefore I would still say this is not a reliable solution to send notification on specific times.

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

If I understood you correctly, I believe that you need setup a recurring alarm using AlarmManager. You also need to setup starting alarm service on device reboot. You can write a method that does what you want so it get executed when the alarm runs e.g. show notification. The following links should help you:

  • Android Fundamentals: Scheduling Recurring Tasks
  • Repeat Alarm Example In Android Using AlarmManager

How To give notifications on android on specific time?

first you need to use a broadcastreceiver. and because a broadcast receiver up only for a short time

from the android developer blog.When handling a broadcast, the application is given a fixed set of time (currently 10 seconds) in which to do its work. If it doesn't complete in that time, the application is considered to be misbehaving, and its process immediately tossed into the background state to be killed for memory if needed.

its a better practice to use also intent service here you have a example how to do it.

this is the broadcast receiver class.

public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}

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

Intent intent1 = new Intent(context, MyNewIntentService.class);
context.startService(intent1);
}
}

and register it in the manifest.

<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="false" >
</receiver>

this is the intent service class.

public class MyNewIntentService extends IntentService {
private static final int NOTIFICATION_ID = 3;

public MyNewIntentService() {
super("MyNewIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("My Title");
builder.setContentText("This is the Body");
builder.setSmallIcon(R.drawable.whatever);
Intent notifyIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
builder.setContentIntent(pendingIntent);
Notification notificationCompat = builder.build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
}
}

and register it in the manifest.

<service
android:name=".MyNewIntentService"
android:exported="false" >
</service>

and then in your activity set the alarm manger to start the broadcast receiver at a specific time and use AlarmManager setRepeating method to repeat it this example bellow will repeat it every day.

 Intent notifyIntent = new Intent(this,MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast
(context, NOTIFICATION_REMINDER_NIGHT, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
1000 * 60 * 60 * 24, pendingIntent);

i hope this will help you.

Creating an android notification that reoccurs every day at some time even when app is closed

You are almost there. Very close just one more thing.
Instead of startService() you should use startForegrounService(). In that case your alarm will always fire. Just a few tips:

  1. you should declare the foreground service in your manifest
  2. You have to use alarmManager.setExactAndAllowWhileIdle for API level higher than 23

You can also check this out for more information.

Update: This method worked forme on Xiaomi Redme note 8, but the just suddenly stopped working! It may not be a very dependable solution for custom OS devices at the moment. Hope google come up with a solid solution.

How to send notification without being online?

Let me add some workaround you can find more tutorial outside..

First create receiver class extends BroadcastReceiver.

public class ReminderReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
int Request_Code = intent.getExtras().getInt("TIME",0);
showNotification(context, MainActivity.class,
"New Notification Alert..!", "scheduled for " + Request_Code + " seconds",Request_Code);
}

public void showNotification(Context context, Class<?> cls, String title, String content,int RequestCode)
{
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

Intent notificationIntent = new Intent(context, cls);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(cls);
stackBuilder.addNextIntent(notificationIntent);

PendingIntent pendingIntent = stackBuilder.getPendingIntent(
RequestCode,PendingIntent.FLAG_ONE_SHOT);

NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = context.getString(R.string.channel_name);
String description = context.getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("my_channel_01", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
notificationManager.createNotificationChannel(channel);
}

NotificationCompat.Builder builder = new NotificationCompat.Builder(context,"my_channel_01");
Notification notification = builder.setContentTitle(title)
.setContentText(content).setAutoCancel(true)
.setSound(alarmSound).setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent).build();

notificationManager.notify(RequestCode,notification);
}

}

Declare receiver in manifest class below activity tag..

 <receiver android:enabled="true" android:name=".ReminderReceiver"/>

Then set reminder to alarm manager.

 public void setReminder(Context context,Class<?> cls,int sec)
{
Intent intent = new Intent(context, cls);
intent.putExtra("TIME",sec);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, sec, intent,
PendingIntent.FLAG_ONE_SHOT);/* Find more about flags: https://developer.android.com/reference/android/app/PendingIntent */

AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (sec * 1000), pendingIntent );//Add time in milliseconds. if you want to minute or hour mutiply by 60.. For ex: You want to trigger 5 Min then here you need to change 5 * 60 * 1000

}

Finally set your reminder

setReminder(_Context,ReminderReceiver.class,time);

Updated

For support android version 8.0 and above you have to create notification channel. Find more here Manage Channels

Add this in above code:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = context.getString(R.string.channel_name);
String description = context.getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("my_channel_01", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
notificationManager.createNotificationChannel(channel);
}

Note use drawable for small icons not use mipmap or adaptive icons.Android Oreo Notification Crashes System UI

To Cancel the scheduled notification

 public void cancelReminder(Context context,Class<?> cls)
{
Intent intent1 = new Intent(context, cls);
intent1.putExtra("TIME",time);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
time, intent1, PendingIntent.FLAG_ONE_SHOT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

if(pendingIntent != null) {
am.cancel(pendingIntent);
}
}

And use above method to delete

cancelReminder(_Context,ReminderReceiver.class);

Note: _Context should be same as used in setreminder() method



Related Topics



Leave a reply



Submit