When the iconIndex of my notification = 0, it looks for the name in the array on position 0, and returns "ic_alert", which is the name of the icon. But only when this icon is chosen, it doesn't want to play the notification sound, even though isPlaySound() returns true, so weird... Other icons work fine
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.e("ALARMRECEIVER","ONRECEIVE");
//Create a notification
long notificationId = intent.getLongExtra("id", -1);
if(notificationId == -1)
{
Log.e("AlarmReceiver","id went missing");
}
else
{
NotificationRepository repository = NotificationRepository.getInstance(context);
Notification notification = repository.getNotification(notificationId);
if(notification != null)
{
String[] icons = context.getResources().getStringArray(R.array.icons);
int iconId = context.getResources().getIdentifier(context.getPackageName()
+ ":drawable/" + icons[notification.getIconIndex()], null, null);
String icon = icons[notification.getIconIndex()];
//create the android notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(iconId)
.setContentTitle(notification.getTitle())
.setContentText(notification.getSubtitle())
.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
if(notification.isPlaySound())
{
mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
Log.e("ALARMRECEIVER", "SOUND");
}
else Log.e("ALARMRECEIVER","NO SOUND");
if (notification.isVibrate())
{
mBuilder.setVibrate(new long[]{1000, 1000});
}
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify((int) notificationId, mBuilder.build());
//Delete the notification from the database
repository.removeNotification(notificationId);
Intent i = new Intent("dvanack.gmail.com.NOTIFY");
context.sendBroadcast(i);
Log.w("ONRECEIVE","ENDED");
}
I don't have this problem with other devices than the One Plus one running Cyanogenmod, this was fixed the day after with an update ...
Related
There is a Reminder application. Now users created 5 Reminders. R1, R2, R3, R4, R5.
And for all reminders time is same. So all reminders came in same time. Now I tap on notification which is R1. and when I tap, it opens a particular activity and show according to details because I sent Id of that reminder in intent.
Now I click on R2/R3/R4/R5, it is opening details according to R1 only instead of R2/R3/R4/R5.
Note: In onReceive, I create notification from that. Also, for all reminders, I open same activity, but details on that activity should be different according to Reminder ID. Also, when I send ReminderId/mReceivedId in intent, it is correct, not the same.
Code:
editIntent = new Intent(context, ReminderDetailActivity.class);
editIntent.putExtra(REMINDER_ID, mReceivedId);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(context, rowId, editIntent, 0);
Complete code (I call createNotification() from onReceive):
private void createNotification() {
int rowId = getRowId(mReceivedId);
Uri mUri;
if (preferenceManager.getRingtoneUri() != null) {
mUri = Uri.parse(preferenceManager.getRingtoneUri());
} else {
mUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
String mTitle = reminder.getTitle();
String id = "1";
PendingIntent pendingIntent;
NotificationCompat.Builder builder;
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
Intent editIntent;
if (SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
assert mNotificationManager != null;
NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
if (mChannel == null) {
mChannel = new NotificationChannel(id, mTitle, importance);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
mNotificationManager.createNotificationChannel(mChannel);
}
builder = new NotificationCompat.Builder(context, id);
editIntent = new Intent(context, ReminderDetailActivity.class);
editIntent.putExtra(REMINDER_ID, mReceivedId);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(context, rowId, editIntent, 0);
builder.setContentTitle(mTitle)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle(mTitle)
.setSmallIcon(R.drawable.ic_alarm_black_24dp)
.setSound(mUri)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Have you completed your task?"))
.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE)
.addAction(R.drawable.ic_icon_alarm, context.getString(R.string.pay_now), pendingIntent);
builder.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
} else {
builder = new NotificationCompat.Builder(context, id);
editIntent = new Intent(context, ReminderDetailActivity.class);
editIntent.putExtra(REMINDER_ID, mReceivedId);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(context, rowId, editIntent, 0);
builder.setContentTitle(mTitle)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle(mTitle)
.setSmallIcon(R.drawable.ic_alarm_black_24dp)
.setSound(mUri)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_icon_alarm, context.getString(R.string.pay_now), pendingIntent)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Have you completed your task?"))
.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE)
.setPriority(Notification.PRIORITY_HIGH);
builder.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
}
Notification notification = builder.build();
mNotificationManager.notify(rowId, notification);
}
Welcome to code party 🎉
As i seen, u want start an activity when another is already opened and it can’t get other extras.
So you must before sending another intent, clear bundle or finish activity.
Edited:
use this in your activity
#Override
protected void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
this.setIntent(intent); //just add this line when overrided
}
do it and update me
My app sets a notification with the following code:
private void defineAndLaunchNotification(String apppack,String title, String ContentText)
{
Context context = getApplicationContext();
PackageManager pm = context.getPackageManager();
Intent LaunchIntent = null;
String name=null;
try {
if (pm != null)
{
ApplicationInfo app = context.getPackageManager().getApplicationInfo(apppack, 0);
name = (String) pm.getApplicationLabel(app);
LaunchIntent = pm.getLaunchIntentForPackage(apppack);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
Intent intent = LaunchIntent;
if (ContentText.equals("filesystemfullnotification"))
{
intent.putExtra("start", "fullsystem");
}
else
{
intent.putExtra("start","incorrecttime");
}
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
NotificationCompat.Builder builder=null;
NotificationChannel notificationChannel=null;
int NOTIFICATION_ID = 12345;
if (Build.VERSION.SDK_INT<26) {
builder =
new NotificationCompat.Builder(getBaseContext())
.setSmallIcon(R.drawable.notification_icon)
.setAutoCancel(true)
.setContentTitle("title
)
.setContentText("Content Text");
}
else
{
int importance=NotificationManager.IMPORTANCE_HIGH;
notificationChannel=new NotificationChannel("mychannel", "channel", importance);
builder =
new NotificationCompat.Builder(getBaseContext(),"mychannel")
.setSmallIcon(R.drawable.notification_icon)
.setAutoCancel(true)
//.setStyle(new NotificationCompat.BigTextStyle().bigText(StaticMethods.giveStringAccordingtoLanguage(title,language)))
.setContentTitle(StaticMethods.giveStringAccordingtoLanguage(title, language))
.setContentText(StaticMethods.giveStringAccordingtoLanguage(ContentText, language));
}
builder.addAction(R.drawable.notification_icon, "OK", pIntent);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
builder.setVibrate(new long[]{0, 1000, 1000, 1000, 1000});
builder.setContentIntent(pIntent);
NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT>=26) {
nManager.createNotificationChannel(notificationChannel);
}
nManager.notify( (int) ((new Date().getTime() +Math.round(Math.random()*5000) / 1000L) % Integer.MAX_VALUE), builder.build());
}
That code sucessfully shows a notification whenever is called, but problem is that if the notification is tapped twice (or more) times it will open as many instances of my application as that number of times.
This happens even though I have defined in my AndroidManifest.xml my application tag with android:launchMode="singleInstance".
What could I do so the notificacion just reacts to the first tap or only one instance of the app appears?
The way you have build the intent you passed into your pending intent could be the problem. Consider building your intent this way:
Intent intent = new Intent(context.getApplicationContext(), <Activity to launch>.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("start", "fullsystem");
By your code you're actually calling to launch the whole application that is why its creating several instances of the application.
You are supposed to launch a particular part of your application, an entry activity to your application.
I am generating local notification with multiple lines. All lines are showing properly but contentTitle and contentText are not showing.
Here is my code to generate a notification:
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
int num = (int) System.currentTimeMillis();
PendingIntent pendingIntent = stackBuilder.getPendingIntent(num, PendingIntent.FLAG_UPDATE_CURRENT);
String id = "notification_channel_id";
CharSequence name = "Message_Notification";
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, id)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("title")
.setContentText("time")
.setAutoCancel(true)
.setGroupSummary(true)
.setGroup(GROUP_KEY)
.setContentIntent(pendingIntent)
.setChannelId(id);
if (subTitle != null) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.setBigContentTitle("Dose Reminder");
if (subTitle.contains("---")) {
String[] splitStrings = subTitle.split("---");
for (int i = 0; i < splitStrings.length; i++) {
inboxStyle.addLine(splitStrings[i]);
}
} else {
inboxStyle.addLine(subTitle);
// Moves the expanded layout object into the notification object.
notificationBuilder.setStyle(inboxStyle);
}
// Moves the expanded layout object into the notification object.
notificationBuilder.setStyle(inboxStyle);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setColor(ContextCompat.getColor(context, R.color.colorAccent));
} else {
notificationBuilder.setLargeIcon(bm);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
// The user.-visible description of the channel.
String description = "Notifications contains messages which was sent by dev team.";
int importance = NotificationManager.IMPORTANCE_MAX;
NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_DEFAULT);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
if (notificationManager != null) {
notificationManager.createNotificationChannel(mChannel);
}
}
// Sets an ID for the notification
// Gets an instance of the NotificationManager service
final NotificationManager mNotifyMgr =
(NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
// Builds the notification and issues it.
if (mNotifyMgr != null) {
mNotifyMgr.notify(num, notificationBuilder.build());
}
When notification comes "title" and "time" are not showing. It showing "Dose Reminder" and subTitles in multiple lines.
Am I missing something?
setBigContentTitle(CharSequence title)
Overrides ContentTitle in the big form of the template.
https://developer.android.com/reference/android/app/Notification.InboxStyle
Check Use MessagingStyle section
https://developer.android.com/training/notify-user/build-notification
JFYI by default timestamp is gone in push notifications, Android 7 (Nougat) onwards
So I have an app that receives the temperature via MQTT. To avoid getting spammed by notifcations, I want the app to notify once, that is vibrate, play sound and then the next three times (if the notification isn't dismissed) it will only update the temperature value. So:
Notify
Update temp
Update temp
Update temp
5(or 1 if you will) Notify
This is my code:
private final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, id);
private void handleNotification(String message, String topic) {
if (notifManager == null) {
notifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
if (isNotifRunning() && ticker < 3) {
updateNotif(message);
ticker++;
} else {
createNotif(message);
ticker = 0;
}
}
private void createNotif(String message) {
Intent intent;
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = notifManager.getNotificationChannel(id);
if (mChannel == null) {
mChannel = new NotificationChannel(id, name, importance);
mChannel.setDescription(description);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200});
notifManager.createNotificationChannel(mChannel);
}
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentTitle(getString(R.string.notifTmpLowTitle))
.setSmallIcon(R.drawable.ic_ac_unit_black_24px)
.setContentText(getString(R.string.notifTmpLowText) + " " + message + Constants.CELSIUS)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(message)
.setColor(getResources().getColor(R.color.colorCold))
.setVibrate(new long[]{100, 200});
} else {
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentTitle(getString(R.string.notifTmpLowTitle))
.setSmallIcon(R.drawable.ic_ac_unit_black_24px)
.setContentText(getString(R.string.notifTmpLowText) + " " + message + Constants.CELSIUS)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(message)
.setVibrate(new long[]{100, 200})
.setColor(getResources().getColor(R.color.colorCold))
.setPriority(Notification.PRIORITY_HIGH);
}
Notification notification = builder.build();
notifManager.notify(NOTIFY_ID, notification);
}
//TODO Doesn't update, posts a new notification.
private void updateNotif(String message) {
builder.setContentText(getString(R.string.notifTmpLowText) + " " + message + Constants.CELSIUS);
Notification notification = builder.build();
notification.flags = Notification.FLAG_ONGOING_EVENT;
notifManager.notify(NOTIFY_ID, notification);
}
//---------------------------------------------
With this code, I always get, what it looks like, a brand new notification with sound and vibration. I've looked at previous questions regarding this and they all say that it's important to use the same builder and as you can see, I have done this. Is there some change in newer Android versions that I'm not aware of? I've tested on both 7.1.1 and 8.1.
You'll want to call setOnlyAlertOnce(true) to cause updates to your notification to not send sound/vibration.
A beginner to android and have been struggling for a while on this problem now. There is an on going notification that I would like to update frequently. Possibly every second. I know this should be possible because I have seen other apps do it like Toggle. But whenever it's updated and there is some other notification on the page, they will keep fighting each other to be on the top. I have researched but haven't found anything that was able to help me on this.
I believe I have followed these rules in hoping of avoiding this issue:
Use the same notification object, and not a new one for every update
Use the same Id on each notify()
Use the .setwhen which was recommended by another post
Video to the problem
private NotificationManager mNotificationManagerupdate;
private NotificationCompat.Builder mBuilderupdate;
/**
* Notification system that is used for this app. All we need to do is call this function
* when we need to trigger a notification.
*/
private void notification() {
times = System.currentTimeMillis();
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.iss_2011);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setAutoCancel(false)
.setOnlyAlertOnce(true)
.setOngoing(true)
.setContentTitle("ISS Tracker")
.setContentText("ISS is about an hour away!")
.setSmallIcon(R.drawable.iss_2011)
.setLargeIcon(icon)
.setSound(soundUri)
.setWhen(times);
Intent resultIntent = new Intent(context, Locations.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(Locations.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(1234, mBuilder.build());
mBuilderupdate = mBuilder;
mNotificationManagerupdate = mNotificationManager;
}
/**
* Continuously updates a notification that will display live results.
*
* #param time The difference between ISS' location to user's location
*/
private void updatemanager(final long time) {
timerupdate = new Timer();
timerupdate.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
notificationupdate(time);
}
}, 0, 1000);
}
/**
* Updates the manager and finishes off when time reaches zero.
*
* #param time The difference between ISS' location to user's location
*/
private void notificationupdate(long time) {
int finalseconds = (int) (time / 1000) - loop++;
if (finalseconds > 0) {
mBuilderupdate.setContentText("ISS is about " + finalseconds + " seconds away!");
} else if (finalseconds > -11) {
mBuilderupdate.setContentText("ISS is at your location! Ending in (" + (10 - Math.abs(finalseconds)) + ")");
} else {
timerupdate.cancel();
timerupdate.purge();
timerupdate = null;
loop = 0;
endnotification = true;
}
mBuilderupdate.setWhen(times);
Log.d(TAG, "When = " + times);
mNotificationManagerupdate.notify(1234, mBuilderupdate.build());
if (endnotification) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nMgr = (NotificationManager) context.getSystemService(ns);
nMgr.cancel(1234);
}
}