I need to generate notifications when a PUSH notification is received but also I need to generate notifications (for display them in the notification bar of the device) when something happens in the application, so I'm using NotificationCompat.Builder for it.
As you know, android has deprecated this call to Notification.Builder:
Notification.Builder (Context context)
And now you must use this call:
NotificationCompat.Builder (Context context, String channelId)
What happens if you don't want to specify a notification channel and you want to send general notifications to all the users of your app and you want to receive all the notifications in all the apps installed without dealing with notification channels? Or what happens if you want to create a simple notification in the notification bar when a user has pressed a button in your app? How to display a notification without specifying the channelId? I mean... just working like until api 26 and before notification channels appeared.
Can't see how to work without specifying notification channels in any place of the official documentation.
Notification Channels are mandatory on Android 8+. So you must use NotificationCompat.Builder(Context context, String channelId) and create channel(s) on api 26+ via NotificationManager.createNotificationChannel(NotificationChannel channel).
On api < 26, just don't call createNotificationChannel but let the channel id parameter (just a String).
val builder = NotificationCompat.Builder(context, "a_channel_id")
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_notif)
.setAutoCancel(true)
...
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(NOTIFICATION_ID, builder.build())
on Api 26+, create a channel before:
val channel = NotificationChannel("a_channel_id", "channel_name", NotificationManager.IMPORTANCE_HIGH)
channel.description = "channel_description"
channel.enableLights(true)
channel.lightColor = Color.RED
channel.enableVibration(true)
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.createNotificationChannel(channel)
There is currently no workaround for this. Notification Channels has been recently announced (last last I/O if I remember correctly), and is (most probably if not absolutely) here to stay. What I do though is something like this.
To abide to the new standard, I just implement the Notification Channels, but only as needed. I also use FCM on my app and here's something similar to what I have for it -- this is in my Application class:
private void initFirebase() {
... // other Firebase stuff.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) initNotificationChannels();
}
#TargetApi(Build.VERSION_CODES.O)
private void initNotificationChannels() {
NotificationChannel publicChannel = new NotificationChannel(NOTIFICATION_CHANNEL_PUBLIC,
NOTIFICATION_CHANNEL_PUBLIC, NotificationManager.IMPORTANCE_DEFAULT);
publicChannel.setDescription(NOTIFICATION_CHANNEL_PUBLIC);
NotificationChannel privateChannel = new NotificationChannel(NOTIFICATION_CHANNEL_PRIVATE,
NOTIFICATION_CHANNEL_PRIVATE, NotificationManager.IMPORTANCE_HIGH);
publicChannel.setDescription(NOTIFICATION_CHANNEL_PRIVATE);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(publicChannel);
mNotificationManager.createNotificationChannel(privateChannel);
}
}
And my MessagingService has something like this:
private static final String NOTIFICATION_CHANNEL_PRIVATE = "my.app.package.name.private";
private static final String NOTIFICATION_CHANNEL_PUBLIC = "my.app.package.name.public";
private void buildNotification(....(other params),String source, String message) {
String channelId = getChannelId(source);
Intent resultIntent = new Intent(this, MyActivity.class);
resultIntent.putExtra(EXTRAS_PARAM_ID, myVal);
PendingIntent notificationIntent = buildNotificationIntent(channelId, roomId, roomType);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, getChannelId(source))
.setSmallIcon(R.drawable.ic_sample
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND)
.setContentIntent(notificationIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(id, 0, notificationBuilder.build());
}
private String getChannelId(String source) {
switch(source){
case PRIVATE:
return NOTIFIFICATION_CHANNEL_PRIVATE;
default:
return NOTIFICATION_CHANNEL_PUBLIC;
}
}
I don't know if this answers the question or not. But, having any channel below api 26 just worked without doing anything on my app.
1. instantiate notificationCompat with some channel Id
//which is irrelevant for api < 26
2. handle the case of creating notification channel for api 26+
3. bundled it up.
It just worked. Configuring Notifications did not have any effects below api 26.
Related
I have a problem with notifications where the notification doesn't appear on my xiaomi and samsung devices but works for the other device. I've tried what people recommend like trying auto start, managing battery settings, but it still doesn't appear on both devices. I also tried to use the notify library but the results were the same. Strangely, when I checked the notification setting and then clicked on the application, it appeared as shown below
samsung
This is my notification code :
public void showNotification() {
String appname = "App Name";
String title = "Notification Title";
String text = "This is the notification text";
String iconUrl = "http://url.to.image.com/image.png";
NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
TaskStackBuilder stackBuilder = TaskStackBuilder.from(MainActivity.this);
stackBuilder.addParentStack(NewsActivity.class);
stackBuilder.addNextIntent(new Intent(MainActivity.this, NewsActivity.class));
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
builder.setContentTitle(title).setContentInfo(appname).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.logo_wanda_flp)).setContentText(text).setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.logo_wanda_flp);
notifyManager.notify("textid", 123, builder.getNotification());
}
The code won't work on Android 8 (API 26) and above without first registering a notification channel. On Android before that, it will work just fine.
Some of the code snippets below are taken from here.
Creating a notification channel
Register notification channels inside your activity before attempting to show any notification. Alternatively, you can register them inside a custom Application class before any activities or services start (but this won't be shown here for the sake of simplicity).
#Override
public void onCreate(Bundle savedInstanceState) {
createNotificationChannel(); // Registering a notification channel
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
private void 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) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
Deliver the notification
public void showNotification() {
// ...
// NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
// Replace with line below.
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID);
// ...
}
I am trying to create notifications in android but no matter what importance and priority I set, there's no sound. I am assuming sound (ringtone) is handle by android itself I don't need to provide any mp3/wav file. I am trying on android 8.1 (actual device), 8.0 (emulator) and 8.1 (emulator). Notification channel created on actual device has sound off by default, I don't know why and on emulator sound is on but still no sound played on notification
Here is my code:
public void sendMessage(View view) {
createNotificationChannel();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("New Notification")
.setContentText("Lorem Ipsum")
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(1, builder.build());
}
private void 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) {
CharSequence name = "basic-channel";
String description = "Lorem Ipsum";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
Channel on Actual Device
Channel on Emulator
Root Cause:
For actual device, that's OEM's problem, which in my case is Xiaomi and I found this link threema.ch/en/faq/notification_channels_xiaomi which says that xiaomi sets sound=off for all app except select few like FB, whatsApp, etc.
For emulator, we need to complete the setup process after which notification starts making sound.
When you build the notification, you need to indicate that you want to use the default system values:
builder.setDefaults(Notification.DEFAULT_ALL)
And remember to clear the app data or reinstall the app to properly recreate the notification channel. A notification channel will retain its initial configuration even if you recreate it in code.
Check this out :
//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("New Notification")
.setContentText("Lorem Ipsum")
.setPriority(NotificationCompat.PRIORITY_HIGH);
.setSound(soundUri); //This sets the sound to play
I did an update on Android Studio recently and after that, I couldn't get my notification showing.
The codes were working fine initially before the update, so I believe the issue is with the software and not the codes. Is there anything I need to change after updating?
My program will actually display a Toast message and also have a notification saying that an account has been registers(after registering an account). However, right after the toast message, another toast message displaying ,"Developer warning for package"com.example.jianminong.aucon" Failed to post notification channel "personal" See log for more details".
public void displayNotification(){
NotificationCompat.Builder builder = new
NotificationCompat.Builder(this,CHANNEL_ID);
builder.setSmallIcon(R.drawable.aucon);
builder.setContentTitle("Welcome " +
editUsername.getText().toString());
builder.setContentText("You have just created an account with
the email of " +editEmail.getText().toString());
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManagerCompat =
NotificationManagerCompat.from(this);
notificationManagerCompat.notify(NOTIFICATION_ID,builder.build());
}
private void createNotificationChannel(){
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O)
{
CharSequence name = "Personal";
String description = "HAHA";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID,name,importance);
notificationChannel.setDescription(description);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
}
}
Are you calling somewhere in your code createNotificationChannel() method that should create the channel for notification? Because if not, the channel is not created, hence the toast message. You can call it before displaying the notification:
public void displayNotification(){
createNotificationChannel()
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,CHANNEL_ID);
...
}
You need to make use of the new notification channels if you are running this on the newer android devices:
Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel or it will not appear.
You need to follow this:
https://developer.android.com/training/notify-user/channels
I have been trying to display a notification but it either doesn't show or causes a fatal error inside the notify method. This notification is supposed to effectively be a toast that will stay in the notification drawer until tapped.
I've tried several different intents including none. I have also, at points, copied an entire example in which still didn't work.
I have no clue what's causing the error and I've tried to attach a logcat into the app but I wasn't able to get anything out.
I'm using a Pixel 2 running stock 8.1; my programming is on the phone itself so I can't use adb / root options
public int noti(String title, String body, String ico){
//Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
showToast(title+">"+body+">"+ico);
try{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
Notification.Builder mBuilder =
new Notification.Builder(getApplicationContext(), "83")
.setSmallIcon(Icon.createWithContentUri(ico))
.setContentTitle(title)
.setContentText(body)
.setOngoing(true)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
Notification noti = mBuilder.build();
if(noti==null){
logBack("noti.builder == null.");
return -2;
}
int notificationId = notiIDz.getAndIncrement();
// notificationId is a unique int for each notification that you must define
notificationManager.notify(notificationId, noti);
return notificationId;
} catch(Exception e){
logBack(e.toString());
}
return -1;
}
I know that the parameters are valid from the toast, I also know that none of the logBack()s are fired.
Notification channel creation, called during onCreate:
private void 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) {
NotificationChannel channel = new NotificationChannel("83", "vzyNotiChan", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("The notification channel for vzy apps.");
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
Edit, finally got to the logcat:07-24 10:48:10.879 27133 27133 E AndroidRuntime: android.app.RemoteServiceException: Bad notification posted from package vzy.html.tester: Couldn't create icon: StatusBarIcon(icon=Icon(typ=URI uri=content://com.android.externalstorage.documents/document/primary%3Ayp_sodapop.png) visible user=0 )
My guess is that you didn't create a notification channel for your notification. On All Android devices running 8.0+, each notification needs to be associated to a notification channel. You're passing in the channel ID "83" to the notification builder, but maybe you haven't actually created the channel beforehand.
For more information on how to create channels, check this out:
https://developer.android.com/training/notify-user/channels
I have followed the Xamarin walkthrough, and it's not working for me.
The code falls through this cleanly, but it never sends the notification.
It never shows up on my emulator or device.
I have no idea what is going on.
public override void OnReceive(Context context, Intent intent)
{
string message = intent.GetStringExtra("message");
string title = intent.GetStringExtra("title");
int id = int.Parse(intent.GetStringExtra("id"));
//Generate a notification with just short text and small icon
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.SetAutoCancel(true) // Dismiss from the notif. area when clicked
.SetContentTitle(title) // Set its title
.SetContentText(message); // The message to display.
NotificationManager notificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
notificationManager.Notify(id, builder.Build());
Any help or links would be very helpful. I'm just completely lost; been working on this for about 14 hours now, and cannot find any help on the Google.
Answer to my inquiry: You must have an Icon set for notifications to be properly build and sent. Though, it won't send an error for not having one.
Short version: Needed to add
.SetSmallIcon(Resource.Drawable.icon);
Add an icon to notification.
Notification.Builder builder = new Notification.Builder (this)
.SetContentTitle ("Title")
.SetContentText ("Message")
.SetSmallIcon (Resource.Drawable.ic_notification);
Notification notification = builder.Build();
NotificationManager notificationManager =
GetSystemService (Context.NotificationService) as NotificationManager;
const int notificationId = 0;
notificationManager.Notify (notificationId, notification);