so we have an iOS app and an Android app that each utilize their respective notification method frameworks... iOS has push and Android has C2DM (until we bring it up to GCM)... all is well on iOS, but i'm looking for a method of detecting if the app was launched by clicking a C2DM message (similar to the functionality of didFinishLaunchingWithOptions on iOS).
Currently, when the push message is received on Android, i do whatever processing that i need to do based on the data contained within the message's payload... so when the user launches the app their experience is determined by what was in that push message. This is the case regardless of whether they launch by pressing the icon on the home screen/history or push message. Ideally we'd like this to happen only if they select that message, and if they select the app from the home/history screen then it should launch normally.
You can save some data in the SharedPreferences on your onMessage listener in the GCMIntentService intent class. The GCM listener belongs to your package app after all.
What you save depends on your app and your message payload, but it may be whatever you want.
Then on your onCreate function of the Activity launched when clicking on the notification, you read the Shared Preferences to see whether you come from the GCM notification or not. Remember to clear the variable you save in the SharedPreferences so that next time that the user opens the app, it displays the content properly.
You have an example here. Unfortunately I cannot try it right now but it's useful to see the idea. It's quite similar to G2DM so you have to look for the equivalent in your case.
public class GCMIntentService extends GCMBaseIntentService {
/*... other functions of the class */
/**
* Method called on Receiving a new message
* */
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("your_message");
// notifies user
generateNotification(context, message);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
// Save your data in the shared preferences
SharedPreferences prefs = getSharedPreferences("YourPrefs", MODE_PRIVATE);
SharedPreferences.Editor prefEditor = prefs.edit();
prefEditor.putBoolean("comesFromGCMNotification", true);
prefEditor.commit();
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
Related
My app sends notifications but the problem is that if there are some notification pending in the action bar, I want to update the message adding the new message to the old message.
For example, if the message is Hi!, and the device receive another message (Pamela) before the user has opened the old message, I want to show only one notification with the message Hi! Pamela.
My code for send notifications is:
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, msg, when);
String title = this.getString(R.string.app_name);
Intent notificationIntent = new Intent(getApplicationContext(),
FirstActivity.class);
notificationIntent.putExtra("message", msg);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
int notifyID = 1;
PendingIntent intent = PendingIntent.getActivity(this, notifyID,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, title, msg, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
Is it possible to get the old message of PendingIntent?
Thanks in advance.
One way to do this is to concatenate the string, by saving what is already displayed like, before the following is called for the first time:
notificationIntent.putExtra("message", msg);
//save "Hi" , concat "Pamela" update the notification with the same notification id
You save the string msg, then concatenate the string that you receive in the next notification. However, to identify, which notifications contain parts of String to be concatenated, is required in this case. Either you can set prefixes to messages or identify by notification id.
Not the ideal way to do it i feel, but can't think of anything else.
It's not possible to retrieve the existing notification from the NotificationManager. You need to keep track of it yourself independently of the notification, and save the unread messages somewhere else (maybe in a SQLite Database or SharedPreferences file).
You will need to determine if the user swipes away the notification, which means you will have to use the NotificationCompat.Builder class to create the notification. You can use the setDeleteIntent method to supply an Intent to trigger when the notification is swiped away, at which point you delete the old messages from wherever you are storing them so that a new message will show a notification with only the new message.
I am developing an application in which i implemented Push notification functionality.
My code of onMessage - GCMIntentService.java is:
#Override
protected void onMessage(Context context, Intent data) {
String message = data.getExtras().getString("message");
displayMessage(context, message);
generateNotification(context, message);
}
And code of generateNotification -
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, GCMMessageView.class);
notificationIntent.putExtra("message", message);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
This code is working fine. I am getting push message and notification.
=>But when i send more then one message the notification gets over write. And i am able to see only last notification in status bar.
The need of application is that - if i send more then one notification then all should be display in status bar.
So please guide me what should i do for that in my code.
Try to put different notification id (i.e. nid) in intent and notify instead of 0 for each new notification this will prevent over writing your notification
PendingIntent intent = PendingIntent.getActivity(context, nid,notificationIntent, 0);
and
notificationManager.notify(nid, notification);
Hope this will help you
Get random numbers:
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
Instead of:
notificationManager.notify(0, notification);
use:
notificationManager.notify(m, notification);
You need to update your Notification ID when you fire a Notification. in
notificationManager.notify(ID, notification);
How?
To set up a notification so it can be different, issue it with a notification ID by calling NotificationManager.notify(ID, notification). To change this notification once you've issued it, create a NotificationCompat.Builder object, build a Notification object from it, and issue the Notification with the Different ID you are not used previously.
If the previous notification is still visible, the system updates it from the contents of the Notification object. If the previous notification has been dismissed, a new notification is created instead.
For more information go to official docs
hello you need to pass unique notification id in notify method.
Below is the code for pass unique notification id:
//"CommonUtilities.getValudeFromOreference" is the method created by me to get value from savedPreferences.
String notificationId = CommonUtilities.getValueFromPreference(context, Global.NOTIFICATION_ID, "0");
int notificationIdinInt = Integer.parseInt(notificationId);
notificationManager.notify(notificationIdinInt, notification);
// will increment notification id for uniqueness
notificationIdinInt = notificationIdinInt + 1;
CommonUtilities.saveValueToPreference(context, Global.NOTIFICATION_ID, notificationIdinInt + "");
//Above "CommonUtilities.saveValueToPreference" is the method created by me to save new value in savePreferences.
Let me know if you need more detail information or any query. :)
notificationManager.notify(Different_id_everytime, notification);
I wanna sync my Activity with Google cloud Messaging.
When GCM message Receives Its own receiver get the message and create notification and then broadcast my custom message to activity receiver.
In other hand my Activity has own dynamically registered BroadcastReceiver that Receives my cusom messsages.
now this is a situation:
when app is open, without clicking on notification, my activity
receiver receives the message and shows.
but when activity is closed after clicking on notification noting
receives and app just opens.
I tried may ways like:
register a class BroadCast receiver On maifest. but I cannot sync it with my activity. cause I found that outer Receiver can sysnc with activity just with putextra and then my activity should close and then open again to can get extras!
try to broadcast my custom message again on creates notification, but it seems wont work cause I need to broad cast on NotificationClick not onCreate notification.
finnaly I tried to Register this internal reciver dynamically on another part of but It cannot reachable.
so if you get my problem what is the best way of solving?
this is my in activity receiver:
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("LOG", "unreciver");
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message
* depending upon your app requirement
* For now i am just displaying it on the screen
* */
//Showing received message
//lblMessage.append(newMessage + "\n");
Log.i("LOG", "unreciver messsage:"+newMessage);
//Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
loadReciverDialog(newMessage);
// Releasing wake lock
WakeLocker.release();
}
};
this is the part of service that receive message from GCM and Create notification:
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("price");
Log.i("LOG", "GCM service Message "+message);
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
private static void generateNotification(Context context, String message) {
Log.i("LOG", "genetaret notify");
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
and this part display message:
static void displayMessage(Context context, String message) {
Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
intent.putExtra(EXTRA_MESSAGE, message);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Log.i("LOG", "commonutils msg="+message);
context.sendBroadcast(intent);
}
I finally solve this problem in this way:
I kept the in-Activity Broadcast Receiver and made a function for checking if Extras exist my codes under OnReceive functions works.
after create notification put message to extra for Main Activity to get them
so my app get message in two way:
when app is opens message will gave with receiver
when app is closed message will gave to app by extra
but I wanna know if there is a better way to work with one Receiver.
In Android, I have implemented Google Cloud Notification, which notifies when any message arrives, but it stays even when message is there, it shows icon in notification bar immediatly after installing application, is there any way to only show the notification when message arrives and hide it once the user clicks on it ??
Here is my code :
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
//Intent notificationIntent = new Intent(context, MainActivity.class); //Open Activity
// set intent so it does not start a new activity
Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
notificationIntent.setData(Uri.parse("http://www.google.com")); //Open Link
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
Without seeing where you are receiving messages and where you want to generate and cancel Notifications, it is very difficult to discern what you need to do to implement this, but I will give it a shot.
If you load the sample project for an Android Connected App Engine project (via GCM), you will notice that GCM data is received in a GCMBaseIntentService.
This class has a method you can override called onMessage() that will be called whenever you receive a GCM message. If you create the notification in this method, then your application will only generate a notification when a GCM message is received.
As for cancelling notifications- you can do so by calling the NotificationManager's cancel() method, passing the ID of the notification you want to cancel. Presumably you have some sort of Activity that displays messages to the user, and this would be a good place to cancel any outstanding Notifications relating to a specific message.
I have a GCMIntentService class, in which i get some messages returned from my server. I want to be able to start a certain activity when a certain message arrives at my app. For example if in my onMessage() method (onMethod() is the method, and the first place, in the app, that receives the messages from the server) arrives the string = "tomatoe", i want to start a specific activity. The way i know right now to start an activity, is this:
Intent resactivity = new Intent(getApplicationContext(), ResponseActivity.class);
resactivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(resactivity);
The problem is that GCMIntentService, is not a class that extends activity, and i believe that i can't use this code for this purpose. Is there some way to initiate an activity from a class that is not an activity, by creating an intent inside that class?
The problem is that GCMIntentService, is not a class that extends activity, and i believe that i can't use this code for this purpose.
GCMIntentService inherits from Context, which is where startActivity() is defined.
Bear in mind, though, that your users may attack you with pitchforks or machine guns for popping up activities at random points in time, perhaps in the middle of something else that they are doing. Please make this behavior configurable, or else make very very certain that your users will appreciate these interruptions.
I post the method I usually use to start an activity when a notification arrives in my apps. Take a look to all the configurations and remove those you are not interested in:
#Override
protected void onMessage(Context context, Intent intent) {
String app_name = context.getString(R.string.app_name);
String message = intent.getStringExtra("payload");
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(ns);
int icono = R.drawable.ic_stat_notify;
long time = System.currentTimeMillis();
Notification notification = new Notification(icono, app_name, time);
notification.defaults |= Notification.DEFAULT_SOUND;
Intent notificationIntent = new Intent(context, ResponseActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, -1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.when = System.currentTimeMillis();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, app_name, message, pendingIntent);
notificationManager.notify(0, notification);
}
You should be able to do it as such:
getApplication().startActivity(resactivity);