I setup GCM and it works fine. I get notifications from the server and they are shown to the client. The problem is, GCM creates its own notification and wont let me make a custom one. I followed this guide: https://github.com/codepath/android_guides/wiki/Google-Cloud-Messaging.
Here is my service code:
public class GcmMessageHandler extends GcmListenerService {
public static final int MESSAGE_NOTIFICATION_ID = 435345;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
createNotification(from, message);
}
private void createNotification(String title, String body) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true);
Intent resultIntent = new Intent(this, RouteActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(RouteActivity.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(MESSAGE_NOTIFICATION_ID, mBuilder.build());
}
}
Anything helps.
from the docs
Message payload is optional. If you are including a payload in the message, use the data parameter to include your custom key/value
pairs. The client app handles the data payload for display or other
processing purposes.
The notification parameter with predefined options indicates that GCM
will display the message on the client app’s behalf if the client app
implements GCMListenerService on Android, or whenever the notification
message is sent to an iOS device. The app server can send a message
including both notification and data payloads. In such cases, GCM
handles displaying the notification payload and the client app handles
the data payload. For more information and examples, see
in other words if you send in your payload a notification tag GCM will create a notification for your app
https://developers.google.com/cloud-messaging/server
Custom layout for notifications in Android, if that's what you mean: Create custom notification, android
Related
I receive notifications from Firebase but my classes I've created not working (not involved in the actions). Seems like they are shown by default.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
String click_action = remoteMessage.getNotification().getClickAction();
Intent intent = new Intent(click_action);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifiBuilder = new NotificationCompat.Builder(this)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notifiBuilder.build());
}
}
There are two types of FCM messages: notification and data. They are handled differently in the receiving device. If you are sending a notification message with no data fields, the notification is generated by the client SDK and onMessageReceived() is not invoked. This is explained in more detail in the documentation:
Notification Message: FCM automatically displays the message to end-user devices on behalf of the client app. Notification messages
have a predefined set of user-visible keys and an optional data
payload of custom key-value pairs.
Data Message: Client app is responsible for processing data messages. Data messages have only custom key-value pairs.
I am only receiving push notification when app is in background, I couldn't find what exactly triggered when my app receive push . I just want to change the notification body , as an example if the notification message is "hi" I want to show user "hi user".
public class MyFcmListenerService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage message) {
//nothing triggered here when app is in background
}
}
$fields = array(
'registration_ids' => $reg_id ,
'priority' => "high",
'data' => array(******));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
I have faced the same problem. Removed notification key values from my PHP firebase Service. My issues got resolved. I am just using registration_ids,
priority, data
You can, you only need to know how firebase push notifications work in android.
you need to override
handleIntent function.
This function handle Firebase notifications in background. So inside it you will make your push notification taking all the data sent in push message. Don't forget extract information from message. You can use default spaces like title or body but also you can send some custom data.
Next I will attach a example code how it works.
Note: if you haven't this method then you need to upgrade firebase version up than 10.0.1
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
}
#Override
public void handleIntent(Intent intent) {
//super.handleIntent(intent);
Log.d(TAG,"Handling Intent");
Bundle mBundle = intent.getExtras();
String img = mBundle.getString("imgURL");
String title = mBundle.getString("gcm.notification.title");
String body = mBundle.getString("gcm.notification.body");
mBundle.putInt("promoId",Integer.valueOf(mBundle.getString("promoId")));
Integer id = mBundle.getInt("promoId");
sendNotification(mBundle);
}
private void sendNotification(Bundle mBundle) {
// Create an explicit content Intent that starts the main Activity.
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
notificationIntent.putExtras(mBundle);
// Construct a task stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Add the main Activity to the task stack as the parent.
stackBuilder.addParentStack(MainActivity.class);
// Push the content Intent onto the stack.
stackBuilder.addNextIntent(notificationIntent);
// Get a PendingIntent containing the entire back stack.
PendingIntent notificationPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Get a notification builder that's compatible with platform versions >= 4
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
String title = mBundle.getString("gcm.notification.title");
String body = mBundle.getString("gcm.notification.body");
// Define the notification settings.
builder.setSmallIcon(R.mipmap.ic_launcher)
// In a real app, you may want to use a library like Volley
// to decode the Bitmap.
.setLargeIcon(BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher))
.setColor(Color.RED)
.setContentTitle(title)
.setContentText(body)
.setContentIntent(notificationPendingIntent);
// Dismiss notification once the user touches it.
builder.setAutoCancel(true);
// Get an instance of the Notification manager
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(0, builder.build());
}
}
if you have any question ask and I will edit mi answer.
hey all i got a tough problem and need advice. I have constructed a notification manually after recieving a FCM data payload. This is how the notification gets created both in foreground and background since its a data payload:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
String msg = remoteMessage.getData().get("message");
sendNotification(msg);
}
private PendingIntent createIntent(String msg) {
Intent intent = new Intent(this, SportsActivity.class);
Bundle b = new Bundle();
b.putString(Constants.KEY_GO_TO_TAB, Constants.KEY_DASHBOARD_HOCKEY_SCORE_TAB);
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
return pendingIntent;
}
private void sendNotification( String messageBody) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
android.support.v4.app.NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(messageBody))
.setContentText(messageBody)
.setColor(ContextCompat.getColor(this, R.color.hockey_brand))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(createIntent(messageBody));
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
it seems to function fine. The issue im having is i want the notification to NOT SHOW in when the app is in the foreground. is there not a way to do this without scanning the activity task ? as this requires a permission
i've read this article but this how to know you've went from foreground to background. also android.permission.GET_TASKS is deprecated and REAL_GET_TASKS permission is not for third party either. I simply want to know at any given time that the user is either in foreground or background so i know if i should show a notification or not. I wonder if firebase itself has something. When you send a "Notification payload" from the firebase console if the app is not in the foreground is does not show in the notification panel so there should be a way to do this.
Alternatively you can choose not to show your notification when your app is in foreground by implementing Application.ActivityLifecycleCallbacks
in your Application.
Then you can check if your app is in foreground or background.
Source
I am implementing push notifications on Android. The problem comes when I want to update my notifications. I would like to stack up notifications so that if a notification is visible I simply update it and do this.
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
But every time I receive a notification ++numMessages is set back to 0 before being summed up. I need it to sum up from where it was left if there is a notification on the screen. Here is the code:
//Class is extending GcmListenerService
public class GCMPushReceiverService extends GcmListenerService {
//variables for message 1,on receiving job applications
String name;
String lastname;
String jobtypename;
String kasualjobdatetimepostedat;
String kasualjobcount;
int numMessages;
//This method will be called on every new message received
#Override
public void onMessageReceived(String from, Bundle data) {
//Getting the message from the bundle
String message = data.getString("message");
String messageid = data.getString("messageid");
if(messageid.compareTo("1")==0){
name=data.getString("firstname");
lastname=data.getString("lastname");
jobtypename=data.getString("jobtype");
kasualjobdatetimepostedat=data.getString("kasualjobdatetimepostedat");
}
else
{
kasualjobcount=data.getString("kasualjobcount");
}
//Displaying a notification with the message
sendNotification(message, messageid);
}
//This method is generating a notification and displaying the notification
private void sendNotification(String message,String messageid) {
Intent intent = new Intent(this, Main_Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Log.d("notificationid", String.valueOf(messageid));
if(messageid.compareTo("2")==0) {//messages to do with jobs around 2
String messageionkasualjobscount="There are "+kasualjobcount+" new jobs around you";
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("KasualJobs2")
.setContentText(messageionkasualjobscount)
.setAutoCancel(true)
.setContentIntent(pendingIntent).setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(2, noBuilder.build()); //messageid = ID of notification
}else{//messages to with users applying for job 1
String messageionkasualjobapplication=name+ " "+ lastname+" has applied for the "+jobtypename+" you posted on "+kasualjobdatetimepostedat;
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("KasualJobs1")
.setContentText(messageionkasualjobapplication)
.setAutoCancel(true).setNumber(++numMessages)
.setContentIntent(pendingIntent).setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, noBuilder.build()); //messageid = ID of notification
}
}
}
In general, you should not expect your field values to persist across multiple calls to onMessageReceived, since the service might have been killed by the OS to free up memory.
I suggest storing your messages in a database. Whenever you receive a new message, insert it into the database, and delete it when the user reads it. Then you can easily query how many unread messages there are.
I suggest you to use FCM instead of GCM (because GCM will no longer used).
And to update notifications use sqlite database for storing the notifications with date & time. clear the notification when read & also delete it from database.
Hi I am trying to send a notification in BroadcastReceiver when receive a broadcast message. from Parse.com. But When call getNotification method from an instance of NotificationCompat.Builder, the notification automatically sent and displayed with a canned contextText. So when call mNotificationManager.notify, TWO notification shows up and one with specified content text and the other one without. I am on API level 16.
Following is my code in BroadcastReceiver, please help me. Thank you very much!
#Override
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getAction();
if (intent.getExtras() != null) {
JSONObject json = new JSONObject(intent.getExtras().getString(
"com.parse.Data"));
String text = json.getString("text");
String title = json.getString("title");
Long timestamp = json.getLong("timestamp");
String qid = json.getString("qid");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText(text)
.setTicker("New Reply");
Intent resultIntent = new Intent(context,
QuestionViewActivity.class);
resultIntent.putExtra(QuestionViewActivity.EXTRA_QUESTION_ID,
qid);
TaskStackBuilder stackBuilder = TaskStackBuilder.from(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = mBuilder.getNotification();
mNotificationManager.notify(qid.hashCode(),
mBuilder.getNotification());
}
I finally got it:
For no build() method: It is caused by ActionBarSherlock using a old version of android-support-v4.jar. Just replace that jar with the updated one from /SDK/extras/android/support/v4/android-support-v4.jar
For the duplicated notification: It is caused by Parse(parse.com) service. When receiving any Push sent with parse notification lib with "title" in the JSON data, the service automatically shows the notification with canned contentText like "you received a notification". A trick here I used to disable the automatic notification is DO NOT use "title" and "text" in the JSON data of parse Push, instead use other names and then parse it in the customized broadcast receiver. It works fine now.
Thanks!
http://developer.android.com/reference/android/app/Notification.Builder.html#build()
getNotification() is deprecated. Why not use build() ?