How to send notification without being online? - android

I am building an app that a user will put their tests and assignments and whatever in. I want to know will it be possible for my app to bring up a notification like a week and a day before the test?
Everywhere I look its just about firebase notifications and push notifications.
I don't want these online notification, I'll need the app to send them by itself offline. Is this possible?

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

I suggest you read Notifications Overview. This well help you to understand how notification works.
To now build the notification, here is the Here is the official documentation for notification.
Read and understand. When you encounter any problem then, you can come back here for the solution.

Related

Want to write a code to only send notification at certain time, but somehow the alarmManager is not working and it shows some errors

Not sending notification at selected time, when I ran my code, directly showed notification
and showed error as well
Here is the error message: E/NotificationManager: notifyAsUser: tag=null, id=12345, user=UserHandle{0}
I thought the error message was due to Build.VERSION.SDK_INT, but after adding that, the error message is still there.
Place all of these under onCreate:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 13);
calendar.set(Calendar.MINUTE,9)
;
Intent intent = new Intent ();
intent.setAction("com.example.Broadcast");
PendingIntent contentIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// PendingIntent alarmIntent = PendingIntent.getBroadcast(this,0, intent,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, contentIntent);
and here is the extend.
public class wakeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
setNotification(context);
}
protected void setNotification(Context context){
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
String ChannelId = "12345";
int uniID = 12345;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,ChannelId )
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("Hi")
.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setContentText("Please Rate.");
builder.setContentIntent(contentIntent);
//
// Send notification to your device
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId("com.myApp");
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"com.myApp",
"My App",
NotificationManager.IMPORTANCE_DEFAULT
);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
manager.notify(uniID, builder.build());
}
}
Can someone please help me with this?
You are very confused.
In your code you call NotificationManager.notify(). This will show the Notification immediately.
You do:
Intent intent = new Intent(this, MainActivity.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this,0, intent,0);
This won't work. You have created a PendingIntent which will be sent via broadcast using an Intent that is for an Activity! What do you want to happen? Do you want an Activity to be launched or do you want a BroadcastReceiver to be triggered?
I think what you want to do is as follows:
Create an Intent for a BroadcastReceiver, wrap that in a PendingIntent using getBroadcast() and pass that to the AlarmManager so that the broadcast Intent will be set at some future time.
Create a class that extends BroadcastReceiver. In onReceive() create the Notification and call NotificationManager.notify() to post the Notification. In the Notification you can set a PendingIntent that opens your Activity so that if the user clicks on the Notification your Activity will be launched. To do this, call PendingIntent.getActivity() and pass an Intent that contains MainActivity.class.

Android notifications not showing

I'm trying to make a daily notification which will be show at a specific time.
Unfortunately it doesn't show.
I tried to follow couples tuto (also from developer.android.com) and checked similar questions that have already been asked. To save hour I'm using Hawk library.
Intent intent = new Intent(getContext(), AlarmReceiver.class);
int notificationId = 1;
intent.putExtra("notificationId", notificationId);
PendingIntent alarmIntent = PendingIntent.getBroadcast(getContext(), 0,
intent,PendingIntent.FLAG_NO_CREATE);
AlarmManager alarm = (AlarmManager) getContext().getSystemService(getContext().ALARM_SERVICE);
switch (view.getId()) {
int hour = timePicker.getCurrentHour();
int minute = timePicker.getCurrentMinute();
// Create time
....
//set alarm
alarm.setRepeating(AlarmManager.RTC_WAKEUP, alarmStartTime, AlarmManager.INTERVAL_DAY, alarmIntent);
Hawk.put("notification_hour", alarmStartTime);
break;
case R.id.cancel_button:
//cancel notification
break;
}
}
and here AlarmReceiver class
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver () {
}
#Override
public void onReceive(Context context, Intent intent) {
sendNotification(context, intent);
}
private void sendNotification(Context con, Intent intent) {
int notificationId = intent . getIntExtra ("notificationId", 1);
String message = " message";
Intent mainIntent = new Intent(con, MainActivity.class);
PendingIntent contentIntent = PendingIntent . getActivity (con, 0, mainIntent, 0);
NotificationManager myNotificationManager =(NotificationManager) con . getSystemService (Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(con);
builder.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle("Reminder")
.setContentText(message)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_ALL);
myNotificationManager.notify(notificationId, builder.build());
}
}
In OREO, they have redesigned notifications to provide an easier and more consistent way to manage notification behavior and settings. Some of these changes include:
Notification channels: Android 8.0 introduces notification channels that allow you to create a user-customizable channel for each type of notification you want to display.
Notification dots: Android 8.0 introduces support for displaying dots, or badges, on app launcher icons. Notification dots reflect the presence of notifications that the user has not yet dismissed or acted on.
Snoozing: Users can snooze notifications, which causes them to disappear for a period of time before reappearing. Notifications reappear with the same level of importance they first appeared with.
Messaging style: In Android 8.0, notifications that use the MessagingStyle class display more content in their collapsed form. You should use theMessagingStyle class for notifications that are messaging-related.
Here, we have created the NotificationHelper class that require the Context as the constructor params. NOTIFICATION_CHANNEL_ID variable has been initialize in order to set the channel_id to NotificationChannel.
The method createNotification(…) requires title and message parameters in order to set the title and content text of the notification. In order to handle the notification click event we have created the pendingIntent object, that redirect towards SomeOtherActivity.class.
Notification channels allow you to create a user-customizable channel for each type of notification you want to display. So, if the android version is greater or equals to 8.0, we have to create the NotificationChannel object and set it to createNotificationChannel(…) setter property of NotificationManager.
public class NotificationHelper {
private Context mContext;
private NotificationManager mNotificationManager;
private NotificationCompat.Builder mBuilder;
public static final String NOTIFICATION_CHANNEL_ID = "10001";
public NotificationHelper(Context context) {
mContext = context;
}
/**
* Create and push the notification
*/
public void createNotification(String title, String message)
{
/**Creates an explicit intent for an Activity in your app**/
Intent resultIntent = new Intent(mContext , SomeOtherActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent resultPendingIntent = PendingIntent.getActivity(mContext,
0 /* Request code */, resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder = new NotificationCompat.Builder(mContext);
mBuilder.setSmallIcon(R.mipmap.ic_launcher);
mBuilder.setContentTitle(title)
.setContentText(message)
.setAutoCancel(false)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setContentIntent(resultPendingIntent);
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());
}
Just include a NotificationChannel and set a channel id to it.

LocalNotification with AlarmManager and BroadcastReceiver not firing up in Android O (oreo)

I've got my local notifications running on androids prior to SDK 26
But in a Android O I've got the following warning, and the broadcast receiver is not fired.
W/BroadcastQueue: Background execution not allowed: receiving Intent { act=package.name.action.LOCAL_NOTIFICATION cat=[com.category.LocalNotification] flg=0x14 (has extras) } to package.name/com.category.localnotifications.LocalNotificationReceiver
From what I've read broadcast receivers are more restricted in android O, but if so, how should I schedule the broadcast if I want it launching even if the main activity is not running?
Should I use services instead of receivers?
This is the AlarmManager launch code:
public void Schedule(String aID, String aTitle, String aBody, int aNotificationCode, long aEpochTime)
{
Bundle lExtras = new Bundle();
lExtras.putInt("icon", f.getDefaultIcon());
lExtras.putString("title", aTitle);
lExtras.putString("message", aBody);
lExtras.putString("id", aID);
lExtras.putInt("requestcode", aNotificationCode);
Intent lIntent =
new Intent(LocalNotificationScheduler.ACTION_NAME)
.addCategory(NotificationsUtils.LocalNotifCategory)
.putExtras(lExtras);
PendingIntent lPendIntent = PendingIntent.getBroadcast(f.getApplicationContext(), aNotificationCode,
lIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager lAlarmMgr = (AlarmManager) f.getSystemService(Context.ALARM_SERVICE);
lAlarmMgr.set(AlarmManager.RTC, 1000, lPendIntent);
}
This is the receiver code:
public class LocalNotificationReceiver extends BroadcastReceiver {
public static native void nativeReceiveLocalNotification (String aID, String aTitle, String aMessage, boolean aOnForeground );
/** This method receives the alarms set by LocalNotificationScheduler,
* notifies the CAndroidNotifications c++ class, and (if needed) ships a notification banner
*/
#Override
public void onReceive(Context aContext, Intent aIntent)
{
Toast.makeText(context, text, duration).show();
}
}
Android manifest:
<receiver android:name="com.category.localnotifications.LocalNotificationReceiver">
<intent-filter>
<action android:name="${applicationId}.action.LOCAL_NOTIFICATION" />
<category android:name="com.category.LocalNotification" />
</intent-filter>
</receiver>
Android O are pretty new to-date. Hence, I try to digest and provide as accurate possible information.
From https://developer.android.com/about/versions/oreo/background.html#broadcasts
Apps that target Android 8.0 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest.
Apps can use Context.registerReceiver() at runtime to register a receiver for any broadcast, whether implicit or explicit.
Apps can continue to register explicit broadcasts in their manifest.
Also, in https://developer.android.com/training/scheduling/alarms.html , the examples are using explicit broadcast, and doesn't mention anything special regarding Android O.
May I suggest you try out explicit broadcast as follow?
public static void startAlarmBroadcastReceiver(Context context, long delay) {
Intent _intent = new Intent(context, AlarmBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, _intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Remove any previous pending intent.
alarmManager.cancel(pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay, pendingIntent);
}
AlarmBroadcastReceiver
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
In AndroidManifest, just define the class as
<receiver android:name="org.yccheok.AlarmBroadcastReceiver" >
</receiver>
Today i had the same problem and my notification was not working. I thought Alarm manager is not working in Oreo but the issue was with Notification. In Oreo we need to add Channel id. Please have a look into my new code:
int notifyID = 1;
String CHANNEL_ID = "your_name";// The id of the channel.
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
// Create a notification and set the notification channel.
Notification notification = new Notification.Builder(HomeActivity.this)
.setContentTitle("Your title")
.setContentText("Your message")
.setSmallIcon(R.drawable.notification)
.setChannelId(CHANNEL_ID)
.build();
Check this solution. It worked like charm.
https://stackoverflow.com/a/43093261/4698320
I am showing my method:
public static void pendingListNotification(Context context, String totalCount) {
String CHANNEL_ID = "your_name";// The id of the channel.
CharSequence name = context.getResources().getString(R.string.app_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationCompat.Builder mBuilder;
Intent notificationIntent = new Intent(context, HomeActivity.class);
Bundle bundle = new Bundle();
bundle.putString(AppConstant.PENDING_NOTIFICATION, AppConstant.TRUE);//PENDING_NOTIFICATION TRUE
notificationIntent.putExtras(bundle);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= 26) {
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
mNotificationManager.createNotificationChannel(mChannel);
mBuilder = new NotificationCompat.Builder(context)
// .setContentText("4")
.setSmallIcon(R.mipmap.logo)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(Color.RED, 300, 300)
.setChannelId(CHANNEL_ID)
.setContentTitle(context.getResources().getString(R.string.yankee));
} else {
mBuilder = new NotificationCompat.Builder(context)
// .setContentText("4")
.setSmallIcon(R.mipmap.logo)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(Color.RED, 300, 300)
.setContentTitle(context.getResources().getString(R.string.yankee));
}
mBuilder.setContentIntent(contentIntent);
int defaults = 0;
defaults = defaults | Notification.DEFAULT_LIGHTS;
defaults = defaults | Notification.DEFAULT_VIBRATE;
defaults = defaults | Notification.DEFAULT_SOUND;
mBuilder.setDefaults(defaults);
mBuilder.setContentText(context.getResources().getString(R.string.you_have) + " " + totalCount + " " + context.getResources().getString(R.string.new_pending_delivery));//You have new pending delivery.
mBuilder.setAutoCancel(true);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
Create the AlarmManager by defining an explicit intent (explicitly define the class name of the broadcast receiver):
private static PendingIntent getReminderReceiverIntent(Context context) {
Intent intent = new Intent("your_package_name.ReminderReceiver");
// create an explicit intent by defining a class
intent.setClass(context, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
Also do not forget to create a notification channel for Android Oreo (API 26) when creating the actual notification:
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (VERSION.SDK_INT >= VERSION_CODES.O) {
notificationManager.createNotificationChannel(NotificationFactory.createNotificationChannel(context));
} else {
notificationManager.notify(NotificationsHelper.NOTIFICATION_ID_REMINDER, notificationBuilder.build());
}
try this code for android O 8.1
Intent nIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
nIntent.addCategory("android.intent.category.DEFAULT");
nIntent.putExtra("message", "test");
nIntent.setClass(this, AlarmReceiver.class);
PendingIntent broadcast = PendingIntent.getBroadcast(getAppContext(), 100, nIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Notification Missing From Intent on Android 7.0

I have an alarm set up to deliver an intent with a notification to a broadcast receiver which then fires the notification. Pre 7.0, the notification is present in the intent when received, on 7.0 it's missing.
Here's the code which generates the notification.
public static void scheduleNotification(Context context, String message, long delay,
MainDisplay.NotificationType type) {
Notification.Builder builder = new Notification.Builder(context).setSmallIcon(
R.drawable.ic_stat_o)
.setContentTitle(
"Title")
.setContentText(
message)
.setStyle(
new Notification
.BigTextStyle()
.bigText(
message));
final Intent notificationIntent = generateNotificationIntent(context);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, builder.build());
notificationIntent.putExtra(TYPE_KEY, type);
final PendingIntent pendingIntent = generatePendingIntent(context, notificationIntent);
final long futureInMillis = SystemClock.elapsedRealtime() + delay;
final AlarmManager alarmManager = (AlarmManager) context.getSystemService(
Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}
Here's the pending intent code.
public static PendingIntent generatePendingIntent(Context context, Intent notificationIntent) {
return PendingIntent.getBroadcast(context, 0, notificationIntent,
PendingIntent
.FLAG_UPDATE_CURRENT);
}
Here's the code that receives it.
public void onReceive(final Context context, Intent intent) {
final NotificationManager
notificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
final Notification notification = intent.getParcelableExtra(NOTIFICATION);
final int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
Any ideas? Thanks!
I noticed that a serialized enum that I sent along was missing as well, I know there were changes in 7.0 with regards to intent transactions that were too large, but I'm not sure how that would apply here as no exceptions were thrown. I opted to simply send along the required info to construct the notification in onReceive.

Incorrect timestamp on future notifications

When my application is launched, it performs an API call and then schedules notifications based on the results. This amounts to around ~10 notifications being scheduled. There seems to be an issue with the timestamp displayed on the actual notification being incorrect.
Since I am creating these notifications and then scheduling an alarm with an AlarmManager, the default time present on the notification will be the time at which the notification is created (System.currentTimeMillis()).
I've tried to use the .setWhen() method on my Notification.Builder to set it to the time I am using to schedule the previously mentioned alarm. This is a little better, however, because notifications are not guaranteed to be delivered at the exact time specified, I often get notifications a few minutes in the past.
Additionally, I tried to manually override the when field on the notification in my BroadcastReceiver, right before .notify() is actually called:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
notification.when = System.currentTimeMillis();
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
However, in the above scenario, it seems that .when is ignored.
Frankly, I am simply looking for a way to have the timestamp displayed on the notification be the time at which it is actually displayed.
I would suggest passing in your notification's information as extras then building the notification inside of the BroadcastReceiver. This will build the notification just before it is issued, so it will have the same time your AlarmManager triggers the BroadcastReceiver.
From wherever you're scheduling the notification:
private void scheduleNotification(){
// Create an intent to the broadcast receiver you will send the notification from
Intent notificationIntent = new Intent(this, SendNotification.class);
// Pass your extra information in
notificationIntent.putExtra("notification_extra", "any extra information to pass in");
int requestCode = 1;
// Create a pending intent to handle the broadcast intent
PendingIntent alarmIntent = PendingIntent
.getBroadcast(this, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Set your notification's trigger time
Calendar alarmStart = Calendar.getInstance();
alarmStart.setTimeInMillis(System.currentTimeMillis());
alarmStart.set(Calendar.HOUR_OF_DAY, 6); // This example is set to approximately 6am
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// Set the alarm with the pending intent
// be sure to use set, setExact, setRepeating, & setInexactRepeating
// as well as RTC_WAKEUP, ELAPSED_REALTIME_WAKEUP, etc.
// where appropriate
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmStart.getTimeInMillis(), alarmIntent);
}
Then, inside your BroadcastReceiver's onReceive:
String notificationExtra = null;
// Retrieve your extra data
if(intent.hasExtra("notification_extra")){
notificationExtra = intent.getStringExtra("notification_extra");
}
//Build the notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setSmallIcon(notificationIcon)
.setContentTitle(notificationTitle)
.setContentText(notificationMessage)
.setAutoCancel(true); // Use AutoCancel true to dismiss the notification when selected
// Check if notificationExtra has a value
if(notificationExtra != null){
// Use the value to build onto the notification
}
//Define the notification's action
Intent resultIntent = new Intent(context, MainActivity.class); // This example opens MainActivity when clicked
int requestCode = 0;
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
requestCode,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
//Set notification's click behavior
mBuilder.setContentIntent(resultPendingIntent);
// Sets an ID for the notification
int mNotificationId = 1;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
I have also been struggling with this for a bit, but your question actually brought me to the best answer. I checked out setWhen() and it seems like now this just works fine (checked with API lvl 30 & 31). As this post is a few years old, maybe this issue was fixed in the meantime. So here's how I did it in Kotlin:
class NotificationPublisher : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notification = intent.getParcelableExtra<Notification>(NOTIFICATION)
notification?.`when` = System.currentTimeMillis() // overwriting the creation time to show the current trigger time when the notification is shown
val postId = intent.getIntExtra(NOTIFICATION_ID, 0)
notificationManager.notify(postId, notification)
}
Your NotificationPublisher's onReceive() method will be invoked only when scheduled alarm triggers as specified time. When you crate a notification from onReceive() method, it will definitely show the current time. No need to require to use .when or .setWhen() method.
Try this one:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
// Notification
Notification notification = new Notification.Builder(context)
.setContentTitle("This is notification title")
.setContentText("This is notification text")
.setSmallIcon(R.mipmap.ic_launcher).build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Notification Manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager .notify(id, notification);
}
}
If you want to redirect to an activity when click on Notification, then you can use PendingIntent and set it to your Notification.
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
Intent intent = new Intent(context, YourTargetActivity.class);
intent.putExtra("KEY_ID", id); // Pass extra values if needed
PendingIntent pI = PendingIntent.getActivity(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Notification
Notification notification = new Notification.Builder(context)
.setContentTitle("This is notification title")
.setContentText("This is notification text")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pI).build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Notification Manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager .notify(id, notification);
}
}
Hope this will help~

Categories

Resources