Hopefully I am phrasing this correctly, but does Android provide a standard mechanism (such as a popup or banner) to display notifications when inside the application? The notifications will be sent to the device via FireBase, once I receive the Notification in the FireBase service onMessageReceived() I want to then display the notification inside the App, so the user can then either let the notice disappear or can react to it (bringing them somewhere else in the application).
So in the Firebase messaging service I want to react to the notification based on the data passed in (I know this will only work with the App in the foreground, but I have implemented other code to handle it in the Intent from the system tray):
public class MyCompanyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
// Do a popup or something to alert the user and then allow them to move to that activity
}
}
Is there a pattern or standard way to do this in Android or is this something I need to code myself? I can't seem to find any reference to it in the Android documentation.
Also, how would this relate to Notification Channels?
Refer to an example here: https://demonuts.com/firebase-cloud-messaging-android/
Follow the method private void generateNotification(String messageBody) in the post.
Starting from Android O and onwards, it is necessary to post the notification in a notification channel. A notification channel helps to group the notification that our app sends.
So in the above post where u create the notification using NotificationCompat.Builder just call method setChannel() and set the created channel. Highlevel steps would be-
Create Notification channel:
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "some_channel_id";
CharSequence channelName = "Some Channel";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel notificationChannel = new
NotificationChannel(channelId, channelName, importance);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500,
400, 300, 200, 400});
notificationManager.createNotificationChannel(notificationChannel);
Create Notification and set channel
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notifyId = 1;
String channelId = "some_channel_id";
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("Some Message")
.setContentText("You've received new messages!")
.setSmallIcon(R.drawable.ic_notification)
.setChannel(channelId)
.build();
notificationManager.notify(id, notification);
Additionally for a detailed description on notification channel follow https://medium.com/exploring-android/exploring-android-o-notification-channels-94cd274f604c
Related
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
Google made a huge breaking change in Oreo - they stopped notifications from working in all apps. I'm now dealing with changing all my apps but I'm left with a couple problems . . .
The notification now gets posted and when the user touches the notification it properly triggers the app. However, (1) the notification does not disappear. To get rid of it the user must delete it. Also (2) the dots on my app icon stay at One after posting several notifications.
I'm using the following notification helper class I found posted by Bipin Pandey:
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 , MainActivity.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.drawable.ticon);
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());
}
}
The following code executes this helper class
NotificationHelper myNotify = new NotificationHelper(context);
myNotify.createNotification("New Message",mesText);
You set setAutoCancel(false), so the notification is correctly not automatically being cancelled when you trigger it. Remove that line if you want tapping on the notification to remove the notification (and the dots associated with the notifications).
You have kept setAutoCancel property as false. So notification won't be dismissed when the user touches it. This is for situations when you want to handle removing the notification at your own end.
Remove that line from your NotificationBuilder and your logic should work as expected.
Description of the Method :
public Notification.Builder setAutoCancel (boolean autoCancel)
Make this notification automatically dismissed when the user touches it.
Read more about Notification Auto Cancel here :
https://developer.android.com/reference/android/app/Notification.Builder.html#setAutoCancel(boolean)
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.
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);