I need to don't receive notifications when my app is killed but I have not found any code that does.
I can receive notifications in foreground and background but they still arrive when I kill the app.
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
try {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getData().get("body"));
}
catch (Exception e){
}
}
//The message which i send will have keys named [message, image, AnotherActivity] and corresponding values.
//You can change as per the requirement.
try {
//message will contain the Push Message
String message = remoteMessage.getData().get("body");
//imageUri will contain URL of the image to be displayed with Notification
String imageUri = remoteMessage.getData().get("image");
String titulo = remoteMessage.getData().get("title");
String sidusuario = remoteMessage.getData().get("sidusuario");
String idnotificacionusuario = remoteMessage.getData().get("idnotificacionusuario");
sendNotification(message, imageUri,titulo);
}
catch (Exception e){
e.printStackTrace();
}
}
This is my sendNotification method
void sendNotification(String messageBody, String icon, String titulo)
{
String channelId = "General";
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setLargeIcon(getBitmapFromURL(icon))
.setContentTitle(titulo)
.setSmallIcon(R.drawable.logo_blanco_chapur)
.setContentText(messageBody)
.setStyle(new NotificationCompat.BigTextStyle())
.setAutoCancel(true)
.setSound(defaultSoundUri);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(getID(), notificationBuilder.build());
}
{
"to": "token",
"notification": {
"title": "title",
"body": "****body****.",
"mutable_content": true
},
"data": {
"url": "https://upload.wikimedia.org/wikipedia/commons/8/80/Coiled_Galaxy.jpg",
"title": "title",
"body": "****body****."
}
}
It maybe duplicates here. Important: if the app is in background or killed then to be received a notification the payload have to remove the notification property
Related
I've created a simple notification and styled it with different colors and general style using a completely new layer created and designed..
Once I trigger the notification though Firebase Messages, when the app is at the foreground, it works perfectly showing the exact styling I need.
But when the app is in the background, it uses it's fugly default style.
Anyway to fix that? Thanks.
The notification java class file code -
public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
private static final String TAG = "FirebaseMessagingServic";
public MyFirebaseMessagingService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
Log.d(TAG, "onMessageReceived: Message Received! \n " +
"Title : " + title + "\n" +
"Message : " + message);
sendNotification(title, message);
}
#Override
public void onDeletedMessages() {
}
private void sendNotification(String title, String messageBody) {
final RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.notification_layout);
remoteViews.setTextViewText(R.id.remoteview_notification_short_message, messageBody);
remoteViews.setTextViewText(R.id.notificationDate, title);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = "0";
Uri defaultSoundUri= Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/raw/notice");
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.minilogored)
.setContentIntent(pendingIntent)
.setContent(remoteViews)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setLights(0xf14d39, 1500, 2000)
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Please refer the link to know more about Data message and Display message how to handle in onMessageReceived() callback function.
How to handle notification when app in background in Firebase
https://firebase.google.com/docs/cloud-messaging/android/receive
I am sending push notification from google firebase for my android app with target of Android 5.0:
My push notification code is:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String badge = "0";
Uri uri = Uri.parse(
getString(R.string.app_host_name)
);
Map<String, String> data = remoteMessage.getData();
if (data.size() > 0) {
try {
uri = Uri.parse(
data.get("link")
);
badge = data.get("badge");
} catch (NullPointerException e) {
//
}
}
if (remoteMessage.getNotification() != null) {
RemoteMessage.Notification notification = remoteMessage.getNotification();
sendNotification(notification.getTitle(), notification.getBody(), uri.toString(), badge);
}
}
private void sendNotification(String title, String body, String url, String badge) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (Patterns.WEB_URL.matcher(url).matches()) {
intent.putExtra("link", url);
}
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Resources resources = getApplicationContext().getResources();
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, "default")
.setColor(
resources.getColor(R.color.colorPrimaryDark)
)
.setSmallIcon(
R.drawable.ic_stat_icon
)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setNumber(Integer.parseInt(badge))
.setLargeIcon(
BitmapFactory.decodeResource(
resources,
R.mipmap.ic_launcher
)
)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel notificationChannel = new NotificationChannel(
"default",
"Main notification channel",
NotificationManager.IMPORTANCE_HIGH
);
notificationManager.createNotificationChannel(
notificationChannel
);
}
notificationManager.notify(
1,
notificationBuilder.build()
);
}
And everything is super perfect when application is active/opened/not in background, but when it is not, notifications are not grouped, there is no number displayed, and no reaction on all of this settings at all, what i was able to change is only small icon and circle color via manifest settings
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/ic_stat_icon" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorPrimaryDark" />
but why? It's like when app is in background notifications are not using settings from Activity code but using only some kind of "default" one from AndroidManifest.
As you said in the comments:
when app is on background, app isn't taking setNumber, setAutoCancel, setSmallIcon, setLargeIcon options
It is because you are using notification payload to send the notification which only triggers on the foreground.
So when your app is in the background it does not enter this method.
to solve this you can use data payload alone:
"data": {
"titles": "New Title",
"bodys": "body here"
}
since the data payload will enter the onMessageReceived() when your app is in foreground/background.
then in fcm you can do this:
if (remoteMessage.getData().size() > 0) {
title = remoteMessage.getData().get("titles");
body = remoteMessage.getData().get("bodys");
}
I need help. As I wrote in title , I don't know how to keep data from notification when it arrives and the application is in background or killed. What i need to pass ( code below) is a Plate that i need for an elaboration . Here is the code:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String text= remoteMessage.getNotification().getBody();
SharedPreferences s = getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE);
Functions.putStringInPrefs(s, Constants.PREFS_ALERT_PLATE, text);
if (Functions.isUserSignedUp(this)) {
if (remoteMessage.getNotification() != null) {
// Log.d(TAG, "Message Title:" + remoteMessage.getNotification().getTitle());
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
try {
sendNotification(remoteMessage.getNotification());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void sendNotification(RemoteMessage.Notification notification) {
Intent intent = new Intent(this, FragmentChangeActivity.class);
String prova = notification.getBody();
intent.putExtra("alert_plate" , prova);
GlobalData.alertPlate=prova; // object used as cache
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if(notification.getTitle()!= null){
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).setContentTitle(notification.getTitle());
} else{
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).setContentTitle(getString(R.string.app_name));
}
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).setContentText(notification.getBody())
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(new Random().nextInt((100000000 - 1) + 1) + 1, new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.details_icon).build());
}
}
What do I need to change ? Thank you !
Ps. In manifest the class is declared in the correct way .
There are two types of FCM messages
1) Notification message
2) Data message
So if you want to receive data when the app is close you have to send your data using data message. Your data format will be something look like below
{
"to": "device_id",
"data": {
"param_1": "vale 1",
"param_2": "value 2",
"param_3": "Value 3"
}
}
After receiving the message now you can store your data in shared preference or database whatever you want.
My MyFirebaseMessagingService.
public class MyFirebaseMessagingService
extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "FRCM:"+ remoteMessage.getFrom());
/*Check if the message contains data*/
if(remoteMessage.getData().size() > 0){
Log.d(TAG,"Message data: "+ remoteMessage.getData());
}
/*Check if the message contains notification*/
if(remoteMessage.getNotification() != null){
Log.d(TAG,"Message body: "+ remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
}
}
/*Display Notification Body*/
private void sendNotification(String body) {
Intent intent = new Intent(this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0/*Request code*/, intent, PendingIntent.FLAG_ONE_SHOT);
/*Set sound of Notification*/
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notifiBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_event_note_black_24dp)
.setContentTitle("Firebase Cloud Messaging")
.setContentText(body)
.setAutoCancel(true)
.setSound(notificationSound)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0/*ID of notification*/, notifiBuilder.build());
intent = new Intent("myAction");
intent.putExtra("title", title);
intent.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
and My Activity Messaging is.
public class Mess{
}
You send messages from your phone using FCM. You need to make a POST to https://fcm.googleapis.com/fcm/send api with payload that you want to send, and you server key found in Firebase Console project or You can Use POSTMAN google chrome extension
As an exameple of payload sending to a single user with to param:
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
Also, to param can be used for topics "to": "topics/yourTopic"
In data you can send whatever you want, message is received in onMessageReceived() service from Firebase.
More details you can found in Firebase documentation.
For sending data to another activity
private void sendNotification(String body) {
Intent intent = new Intent(this, Home.class);
here you can set intent
intent.putExtra("word", body);
and to read from activity use
b = getIntent().getExtras();
String passed_from = b.getString("word");
I've looked fairly extensively across a wide range of terminology ("banner", "pop down", "notification type") and I can't seem to find clarity on what I 'think' is a very common issue. So if there is a very obvious solution I missed due to my lack of terminology please advice.
The problem is this:
I want an Android notification to appear as a "banner" that drops down from the top of the screen (if banner is the wrong word for this please advise). I went through the Docs and didn't seem to across a setting that toggles this behaviour. Here is an example of what I would like:
I have the notification working but it currently only showing up inside the drawer. It's not popping down from the drawer (which is what I want).
Here is my code, if you can advise how I can make it also appear as a banner I would greatly appreciate it:
public void createNotification(Context context, Bundle extras)
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String appName = getAppName(this);
Intent notificationIntent = new Intent(this, PushHandlerActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("pushBundle", extras);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int defaults = Notification.DEFAULT_ALL;
if (extras.getString("defaults") != null) {
try {
defaults = Integer.parseInt(extras.getString("defaults"));
} catch (NumberFormatException e) {}
}
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setDefaults(defaults)
.setSmallIcon(context.getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
.setContentTitle("NotificationTitle")
.setTicker(extras.getString("title"))
.setContentIntent(contentIntent)
.setAutoCancel(true);
String messageJson = extras.getString("data");
JSONObject parsed;
String message = null;
try {
parsed = new JSONObject(messageJson);
message = parsed.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
if (message != null) {
mBuilder.setContentText(message);
} else {
mBuilder.setContentText("Notification");
}
String msgcnt = extras.getString("msgcnt");
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
int notId = 0;
try {
notId = Integer.parseInt(extras.getString("notId"));
}
catch(NumberFormatException e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage());
}
catch(Exception e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
}
mNotificationManager.notify((String) appName, notId, mBuilder.build());
}
See: http://developer.android.com/design/patterns/notifications.html
You want a Heads-Up Notifications. This requires you to set the priority with the Notifications Builder (.setPriority) to high or max.
http://developer.android.com/design/patterns/notifications.html#correctly_set_and_manage_notification_priority
The app in background basically doesn't call onMessageReceived() method.
Only when notification doesn't have notification key, the app in background call onMessageReceived() method.
So, do not use notification key.
{
"to": "/topics/notice",
"notification": {
"title": "title",
"body": "body"
},
"data": {
"url": "https://your-url.dev"
}
}
only use data key.
{
"to": "/topics/notice",
"data": {
"title": "title",
"body": "body"
"url": "https://your-url.dev"
}
}
And set priority to max.
notificationBuilder.setContentTitle(title)
// ...
.setPriority(NotificationCompat.PRIORITY_MAX)
// ...
;
Then, you'll archive what you want.
Orion Granatir is right.
For Xamarin.Android developers, here is the code:
//Create the notification
var notification = new Notification(Resource.Drawable.icon, title);
//Auto-cancel will remove the notification once the user touches it
notification.Flags = NotificationFlags.AutoCancel;
notification.Sound = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
notification.Defaults = NotificationDefaults.Vibrate | NotificationDefaults.Lights;
notification.BigContentView = new Android.Widget.RemoteViews(AppSettings.Instance.PackageName, Resource.Layout.notification_template_big_media);
notification.LargeIcon = BitmapFactory.DecodeResource(Resources, Resource.Drawable.icon);
notification.Priority = (int)Android.App.NotificationPriority.Max;//A notification that is at least Notification.PriorityHigh is more likely to be presented as a heads-up notification.
You basically need to understand how WindowManager works.
You get the
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
then you want to get the root view and use the method addView(view, params) if you want to add a view.
Take a look at this cool article, which might help your use case.