My notification doesn't appear when I click in my button - java

With this code, I want to click in a button and appear a notification.
The problem is when in click in my button doesn't appear any notification.
I search in youtube, in example codes and I don't see my error, can you see??
btNotify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notification();
}
});
public void notification() {
NotificationCompat.Builder builder = new
NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.ic_baseline_access_time_24);
builder.setContentTitle("Time");
builder.setContentText("Isto é um relógio");
NotificationManager notifManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notifManager.notify(1, builder.build());
}

You didn't mention the android version you are working with.
According to the official documentation you have to provide a channel to the builder constructor when using API level 26+ (Android 8 or higher).
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
It is recommended to create the channel right on start-up of the app since you can not post notifications without it (again, this is valid for API level 26+).
Don't forget to assign a priority to the channel.
You can find the details about creating a channel here.
Anyways, notifications are usually used for providing information to the user while the app is NOT in use.
If you just want an instant notification following a button press, could you also consider using a Toast or a snackbar?
It can be as simple as:
Toast.makeText(yourContext, "Your message", Toast.LENGTH_LONG).show()
Update 2020/08/11
Update according to the android version you mentioned.
The android documentation states the following:
Notice that the NotificationChannel constructor requires an importance, using one of the constants from the NotificationManager class. This parameter determines how to interrupt the user for any notification that belongs to this channel—though you must also set the priority with setPriority() to support Android 7.1 and lower (as shown above).
by using the NotificationCompat builder, you get upward compatibility with android 8+ by creating a channel and providing it to the NotificationCompat constructor. For lower versions the channel is simply ignored.
A priority setting is strictly required for using notifications. For support with versions lower or equal to Android 7.1: you need to set the priority in the builder since the channel (which has a priority setting on its own) is ignored.
Try adding the required importance specification with setPriority in the builder:
val builder ...
.setPriority(NotificationCompat.PRIORITY_DEFAULT) // or any other priority level
Update 2020-08-17
How to create a Channel for API level 26+ as shown in the official documentation:
private fun 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) {
val name = getString(R.string.channel_name)
val descriptionText = getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}

Related

How to create more than one foreground notification?

Below is a snippet of code in my service class.
If a user "joins a team" (operation = 0) then it create a notification with its designated specifications however if a user shares their location (operation = 1) then its supposed to create a separate foreground notification. Instead one just replaces the other.
I don't know why, they have different ID's just same channel. I've also tried separating their channel ID, still the same issue
int id = NOTIFICATION_LOCATION;
int icon = R.drawable.ic_gps_on;
String message = "Tap to disable location updates";
if (operation == 0) {
id = NOTIFICATION_RESPONDER;
icon = R.drawable.ic_responder_icon;
message = "Tap to leave the responding team";
}
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID_1)
.setSmallIcon(icon)
.setContentTitle("Location established")
.setContentText(message)
.setContentIntent(PendingIntent.getBroadcast(getApplicationContext(), 0, getBroadcastIntent(operation), PendingIntent.FLAG_UPDATE_CURRENT))
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.primaryColor))
.setDefaults(Notification.DEFAULT_SOUND)
.setVisibility(VISIBILITY_PUBLIC)
.build();
startForeground(id, notification);
The notification you manipulate with startForeground() is meant to be the one "official" notification that corresponds to the foreground service; the one that Android insists you have up at all times the service is running.
It doesn't surprise me that, if you supply a different notification channel ID on a subsequent call to startForeground(), it erases and replaces the original notification. Otherwise, you might end up with multiple foreground notifications for a single service, and things could get confusing.
Instead, just use NotificationManager.notify() to manage any notifications that occur in excess of the original foreground service notification. Use distinct IDs for these extra notifications.
A good practice is to use a fixed ID for your foreground service notification. You can still change the Notification at will; it's just easier to remember which Notification is your "official" one, when you have a fixed ID.
You can also manipulate your "official foreground service notification" using notify(); you don't have to use startForeground(). A call to startForeground() is only needed once, at the beginning, to associate the service with a specific notification ID.

How to change app notification badge count programmatically without sending notification (java/android)

I want to change the notification badge count every time a user arrives at the home page (or presses a button for testing purposes). The only way I can do that right now is by sending a notification like so:
Notification notification = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build();
However, I want to change the badge count without sending a notification as I don't want to clutter up the notification panel.
Welcome to StackOverflow.
It would appear the pacakge you're using is no longer maintained, as it's been deprecated in favour of AndroidX and I'd recommend migrating to that if it's an option for your project.
If I'm correct in my assumption, you're attempting to do something similar to what you can achieve on iOS, however the Android SDK does not support this out of the box, although there appears to be a workaround
As such, the function you're calling cannot be used for that particular purpose. The setNumber function sets the number displayed in the long press menu
All this having been said
You CAN update a notification that's already been sent, and update the number shown in the long press menu using the setNumber method, as detailed in this article
TL;DR:
Post the notification with an identifier using the following method and save the identifier somewhere for later: NotificationManagerCompat.notify(notificationId, builder.build());
Rerun the same code you posted in your question, updating the badge number in the process
Run NotificationManagerCompat.notify() again, passing the SAME notification id and the NEW notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
int notificationID = 123456;
int messageCount = 1;
Notification notification = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build();
notificationManager.notify(notificationID, notification);
//Now update the message count
messageCount++;
Notification notification = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build();
notificationManager.notify(notificationID, notification);

Oreo & Pie Notifications

Problem: My app needs notifications that can be customized by the user. eg. set different sounds, titles, texts for notifications
Issue: I'm aware notification channels are set only once and cannot be modified so I thought I could just use variables however even with variables once I have picked a sound it stays as that sound and cannot be changed at all. The only solution I can think is a new channel each time something is changed which just seems silly.
Surely there is another way??
Also to add to all of this, on Android Pie the notification sound does not work at all I can't work out why.
Uri soundUri = Uri.parse(notificationSound);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "CH_ID")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(customTextTitle)
.setContentText(customTextBody)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if(soundUri != null){
// Changing Default mode of notification
notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
// Creating an Audio Attribute
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
// Creating Channel
NotificationChannel notificationChannel = new NotificationChannel("CH_ID","Testing_Audio",NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setSound(soundUri,audioAttributes);
mNotificationManager.createNotificationChannel(notificationChannel);
}
}
mNotificationManager.notify(0, notificationBuilder.build());
}
I have solved the problem albeit in a hacky way :( I have ended up setting the sound to null if >=Oreo and using a media player to play the notification sound also setting the audioStream to STREAM_NOTIFICATION. Obviously not ideal but as it's a notification and not an alarm the audio shouldn't go over the time set to perform task during onReceive.
The only problem I can see with this solution is if the user decides to mute the notification/make adjustments to the channel on their phone. Muting the sound there obviously will have no effect to the sound played by media player and will most likely show as no sound anyway which is unfortunate.
try {
mp.setDataSource(context.getApplicationContext(), soundUri);
mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mp.prepare();
mp.start();
} catch (Exception e) {
//exception caught in the end zone
}
For anyone else having this issue I found a really great post here which is the same solution as mine but more robust and in more depth. Android O - Notification Channels - Change Vibration Pattern or Sound Type
you have wrong implemented, set sound like below
notificationBuilder.setSound(soundUri,audioAttributes);

Android NotificationChannel compatability with older API

I'm new to android development and Java, and I'm slightly confused about the handling of backwards compatibility when using classes that have been introduced in the latest versions.
I've checked out the android support library and see the various XXXCompat classes available. For the ones I've looked at they appear to pretty much branch on VERSION.SDK_INT and call a new api or an old api.
I am using a support library (com.android.support:support-v4:27.1.1) version that is targeted for a newer api than my targetSdkVersion (25). I was under the impression this was the intended use case? to be able to write code with newer api's but have it work when targeting older sdk.
If so, how is this possible? For instance ContextCompat is has the following for startForegroundService
public static void startForegroundService(#NonNull Context context,
#NonNull Intent intent) {
if (VERSION.SDK_INT >= 26) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
However in the version I am targeting the Context doesn't have the method startForegroundService. If paste this if block into my code, it fails to compile with java: cannot find symbol ....
I can only assume that even if you compiled against a newer api (such that it could resolve the symbols), if those symbols don't exist at runtime, as long a they are not called it is not a problem?
So this is fine for api calls that are abstracted by the XXXCompat classes, but when using new classes like NotificationChannel. I can only import this if upping my targetSdkVersion to > 26. So assuming I do this, then this class is available. All uses of it that I have seen do
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = ...
}
Does this mean that at runtime, for lower Build.VERSION.SDK_INT the symbol NotificationChannel will not exist? and if I attempted to instantiate this class it on a lower android version, it would crash?
Before Oreo, you can just start your service. For Oreo and higher, the service needs to run in foreground and thus post a notification upon service start otherwise it gets destroyed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
To post notification in Oreo and above you need to create a notification channel, before Oreo you just add your channel id to the notification builder (no need to create a channel). Snippet code from service:
String channelId = "myAppChannel"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// build notification channel
createNotificationChannel(channelId, ...)
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId)
// Build your notification
Notification notification = notificationBuilder
.setOngoing(true)
.setSmallIcon(icon)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
// post notification belonging to this service
startForeground(NOTIFICATION_ID, notification)
When you create createNotificationChannel function, just annotate it with #RequiresApi(26).

How to show a notification without a sound java

How can I make a notification that doesn't make a sound when I build it? I am building a notification, and my users don't like the fact that it makes a sound.
How can I change it to a silent one / no sound at all?
How I show notification:
android.support.v7.app.NotificationCompat.Builder builder = new android.support.v7.app.NotificationCompat.Builder(main);
builder.setStyle(new android.support.v7.app.NotificationCompat.BigTextStyle().bigText(text));
builder.setSmallIcon(R.drawable.app);
builder.setContentTitle("Rooster Maandag:");
builder.setOngoing(false);
builder.setAutoCancel(true);
builder.setSilent(true);
builder.setDefaults(Notification.DEFAULT_ALL);
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
notificationManager = (NotificationManager) main.getSystemService(main.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
I tried to search on google, but the only results I get is HOW to play a sound, not HOW to not play a sound...
Edit
It possibly is a duplicate in some people's eyes, but in mine I could not find out an alternative for the there specified default, while this new method is called setDefaults
To disable the sound in OREO 8.1, change the priority of the notification as LOW and it will disable the sound of notification:
NotificationManager.IMPORTANCE_LOW
The code is like:
NotificationChannel chan1 = new NotificationChannel("default", "default", NotificationManager.IMPORTANCE_LOW);
It works for me in Android Oreo.
You should just write your channel like this:
NotificationChannel notificationChannel = new NotificationChannel("Id" , "Name", NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setSound(null, null);
notificationChannel.setShowBadge(false);
notificationManager.createNotificationChannel(notificationChannel);
NotificationCompat.Builder.setSilent(true)
This works regardless of the Notification Channel setting. This allows you to have a channel that makes sound by default but allows you to post silent notifications if desired without making the entire channel silent.
Reference:
https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder#setSilent(boolean)
Remove the line to builder.setDefaults(Notification.DEFAULT_ALL);. It will not play the sound, but you may need to enable all other notification defaults if preferred
I might be late but still wants to add this . You can disable sound using .setSound(null) on NotificationCompat.Builder builder for all OS below O.
For O version n above add channel.setSound(null,null) after creating NotificationChannel channel
All the solutions above mine is either outdated or covers some OS versions only
In android O, for me it worked with this settings in the notification:
.setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
.setGroup("My group")
.setGroupSummary(false)
.setDefaults(NotificationCompat.DEFAULT_ALL)
i had used this piece of code in NotificationCompat.Builder try this,
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setNotificationSilent();
Use this If you want all (sound, vibration and lights) in notifications.
builder.setDefaults(Notification.DEFAULT_ALL);
Or you can enable or disable items based on your requirements.
builder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
comment this line if you want nothing.
Easy way to go to be able to show notification with any kind of priority is to set some sound that is silence actually. Just generate some silence.mp3 put it in "raw" folder and set notification sounds using Uri:
Uri.parse("android.resource://"+YOUR_APP_PACKAGE_NAME+"/"+R.raw.silence)
You can generate this .mp3 with app like Audacity. It has option generate silence, just set how many seconds and you are good to go.
If you set defaults to 0 and set sound to null, notification will be shown without you hearing it but you wont be able to show notifications with some higher priority.
use that exact code:
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_DEFAULT);
NOTIFICATION_CHANNEL_ID --> random String.
channelName ==> random string
You can set more than one channel.
In my case, my aplication has a background service with two sounds notifications, and one notification without sound. I get it with this code:
//creating channels:
NotificationChannel channel1 = new NotificationChannel(CHANNEL_ID_1, "CarNotification1", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel2 = new NotificationChannel(CHANNEL_ID_2, "CarNotification2", NotificationManager.IMPORTANCE_MIN);
NotificationChannel channel3 = new NotificationChannel(CHANNEL_ID_3, "CarNotification3", NotificationManager.IMPORTANCE_HIGH);
//mSound1 and mSound2 are Uri
channel1.setSound(mSound1, null);
channel3.setSound(mSound2, null);
and when I create the notification:
String channelId;
switch (situation){
case situation2:
channelId=CHANNEL_ID_2;
break;
case situation1:
channelId=CHANNEL_ID_1;
break;
default:
channelId=CHANNEL_ID_3;
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
//etcetera

Categories