get notification intent extras - android

My notification Show Method:
public static void ShowNotification(int id, String NotifFirstText,
String NotifTitle, String NotifeText, int notificon, long when) {
try {
Context context = ApplicationClass.context;
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(context.NOTIFICATION_SERVICE);
int icon = notificon;
CharSequence notiText = NotifFirstText;
long meow = when;
Notification notification = new Notification(icon, notiText, meow);
CharSequence contentTitle = NotifTitle;
CharSequence contentText = NotifeText;
Intent notificationIntent = new Intent();
String mPackage = "mypackage";
String mClass = ".ActivityShow";
notificationIntent.setComponent(new ComponentName(mPackage,
mPackage + mClass));
notificationIntent.putExtra("id", id);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.flags = Notification.DEFAULT_LIGHTS
| Notification.FLAG_AUTO_CANCEL
| Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND;
PendingIntent contentIntent = PendingIntent.getActivity(G.context,
0, notificationIntent,0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
int SERVER_DATA_RECEIVED = id;
notificationManager.notify(SERVER_DATA_RECEIVED, notification);
} catch (Exception e) {
e.printStackTrace();
}
}
and this my activity code:
if (getIntent().getExtras() != null) {
Toast.makeText(getBaseContext(),
getIntent().getExtras().getInt("id") + "", Toast.LENGTH_LONG).show();
}
i create more than one notification and set different id for All of them but when i click on each notification i give same id ...
how solve this problem?

When you use PendingIntent.getActivity(G.context, 0, notificationIntent,0), extras do not get replaced per the PendingIntent overview:
Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.
While in most cases you'd replace the last 0 with FLAG_UPDATE_CURRENT to update the extras, this doesn't help the problem of having multiple notifications simultaneously, instead they say:
If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents.
The easiest way to do this is to pass in your id as the request code (the second parameter). This ensures that each PendingIntent is managed separately:
PendingIntent.getActivity(G.context, id, notificationIntent, 0)

Related

Android Notification Problems When more than one

I build simple app with used GCM and notification, I already success implement that, but I have question about notification, in my case:
I got more than one notification,
Example
Notif_1 -> Title : test_1 , Message : test_message_1
Notif_2 -> Title : test_2 , Message : test_message_2
Notif_3 -> Title : test_3 , Message : test_message_3
Notif_4 -> Title : test_4 , Message : test_message_4
The problem I just always got last notification bundle when I tap notification.
So when I tap notif_1, I got bundle from notif_4
when I tap notif_2, I got bundle from notif_4
What I want is when I tap notif_1, must have bundle from notif_1 not from other notif
how to make like that?
private void sendNotification(String title, String msg) {
mNotificationManager =
(NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(ctx, BuyLevel.class);
Bundle bundle = new Bundle();
bundle.putString("title", title);
bundle.putString("message", msg);
resultIntent.putExtras(bundle);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(ctx);
stackBuilder.addParentStack(BuyLevel.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx);
mBuilder.setSmallIcon(R.drawable.icon_mini);
mBuilder.setContentTitle(title);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(msg));
mBuilder.setContentText(msg);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setAutoCancel(true);
Notification notification = mBuilder.build();
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
int initialNotification = CommonUtilities.msgId.incrementAndGet();
mNotificationManager.notify(initialNotification, notification);
}
Flag must be required with unique values. So we can set flag as random number.
Change this line:
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
to
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, m);
According to the documentation of PendingIntent:
If the creating application later re-retrieves the same kind of
PendingIntent (same operation, same Intent action, data, categories,
and components, and same flags), it will receive a PendingIntent
representing the same token if that is still valid.
[...]
A common mistake people make is to create multiple PendingIntent
objects with Intents that only vary in their "extra" contents,
expecting to get a different PendingIntent each time. This does not
happen. The parts of the Intent that are used for matching are the
same ones defined by Intent.filterEquals. If you use two Intent
objects that are equivalent as per Intent.filterEquals, then you will
get the same PendingIntent for both of them.
If you truly need multiple distinct PendingIntent objects active at
the same time (such as to use as two notifications that are both shown
at the same time), then you will need to ensure there is something
that is different about them to associate them with different
PendingIntents.
[...]
This may be any of the Intent attributes considered by
Intent.filterEquals, or different request code integers supplied to
getActivity(Context, int, Intent, int), getActivities(Context, int,
Intent[], int), getBroadcast(Context, int, Intent, int), or
getService(Context, int, Intent, int).
So your code when requesting the PendingIntent should be something like:
int m=0;
private void sendNotification(String title, String msg) {
mNotificationManager = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
[...]
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(m++,
PendingIntent.FLAG_UPDATE_CURRENT);
[...]
}

Bundle data is not updating in the activity passed from a notification in service, always populating the first bundle

I am handling push notification in my application using GCMIntentService. I am creating a status bar notification and navigating to an activity using pending Intent.
my Code for creating a notification is :
private static void generateNotification(Context context, String message, String title1, String desc, String soln, String date, String time) {
int icon = R.drawable.notification_icon;
long when = System.currentTimeMillis();
Log.i("","###### notificatin"+title1+desc+soln+message);
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,AppLog.class);
notificationIntent.putExtra(Description.REQUEST_FROM, "notification");
notificationIntent.putExtra(Description.INFO_TITLE, title1);
notificationIntent.putExtra(Description.INFO_DESC, desc);
notificationIntent.putExtra(Description.INFO_SOLUTION, soln);
notificationIntent.putExtra(Description.INFO_DATE, date);
notificationIntent.putExtra(Description.INFO_TIME, time);
PendingIntent pIntent = PendingIntent.getActivity(context, 0,notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notification.sound=uri;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
And inside my AppLog.class I am handling it like :
if(bundle!=null && bundle.containsKey(Description.REQUEST_FROM)){
Log.i("","###### applog"+bundle);
}
When the first notification is sent to the device data will be populated correctly in my AppLog Activity class. But onwards for all notifications it always show me the old bundle.
I tried everything but still the issue persist. Is there any issue with pending intents or notification created from services ?
This works
PendingIntent pIntent = PendingIntent.getActivity(context, 0,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Instead of always passing a 0 value as the second parameter try and pass a random number.
Random r = new Random();
int no = r.nextInt(999999);
PendingIntent pIntent = PendingIntent.getActivity(context, no,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

How to send 2 strings using Notification?

I'm trying to send 2 strings using Notification, but I don't know how should I do it. I used putExtra for my strings, but on the other activity I get null. I don't know what to do on the other activity. I read about this on net, but I didn't undersand. Can anyone help me?
Here is my code :
private void setNotifiy(){
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence NotificationTicket = "You have a notification";
//CharSequence NotificationContent = ;
CharSequence contentTitle = "You are close to "+name_shop+"!!!";
CharSequence contentText ="So,you can go for shopping:)";
long when = System.currentTimeMillis();
Notification notification = new Notification(R.drawable.icon,
NotificationTicket, when);
Context context = getApplicationContext();
Intent notificationIntent = new Intent(this, ShopsOnMap.class);
notificationIntent.putExtra("latshop",lat_choose);
notificationIntent.putExtra("longshop", long_choose);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(NOTIFICATION_ID, notification);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
}
In the class ShopsOnMap I wrote just this :
String q = getIntent().getStringExtra("latshop");
System.out.println("!!"+q+"$$");
and I obtain q=null.
I need a simple example, or any idea that could help me. Thanks.
Use FLAG_UPDATE_CURRENT in your getActivity() call, instead of 0, for the fourth parameter, so your new Intent extras are applied to the PendingIntent.

Cannot open first notification but opens for the rest

I have some kind of SMS application. So everytime the phone received a new message, it should have a notification and upon clicking it, will launch the activity. Right now, when receiving 1 message, it notifies, removes in the status bar and doesn't not launch the activity. But when receiving 2 or more messages, the first notification cannot launched upon clicking while the rest(2nd, 3rd notification...) can. Below are my codes.
Intent newIntent = new Intent(context, PreviewActivity.class);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK+0);
newIntent.setAction(strFxPrimaryKey);
Bundle newBundle = intent.getExtras();
newBundle.putInt(GlobalConstants.PRIMARY_ID, Integer.parseInt(strFxPrimaryKey));
newIntent.putExtras(newBundle);
int icon = R.drawable.notification_fx;
CharSequence tickerText = context.getString(R.string.fx_received);
long when = System.currentTimeMillis();
Notification newNotification = new Notification(icon, tickerText, when);
newNotification.flags |= Notification.FLAG_AUTO_CANCEL; //| Notification.FLAG_ONGOING_EVENT;
PendingIntent contentIntent = PendingIntent.getActivity(context, Integer.parseInt(strFxPrimaryKey), newIntent, 0);
newNotification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
String newNotificationService = Context.NOTIFICATION_SERVICE;
NotificationManager newNotificationManager = (NotificationManager) context.getSystemService(newNotificationService);
newNotificationManager.notify(Integer.parseInt(strFxPrimaryKey), newNotification);
context.startActivity(newIntent);
context.removeStickyBroadcast(intent);
Based on the answers here in the stackoverflow, to create a unique intent, it should have unique action that's why I set the primary key as the action. I also set the request code to primary key to have a unique pending intent. Is there something missing out in my code? Thanks.
EDITED
By the way, whenever I remove the context.startActivity(newIntent);, it works right. Can anyone tell me why? Thanks.

Notification getIntent().getExtras() gets the same bundle

The problem im having is I call sendAffimationNotice() twice passing a unique aff_id each time (as confirmed by printing "putting " + aff_id).
This prints 'putting 1' and on the second call 'putting 2'.
The phone now has 2 notifications. Though when both are clicked they both have the same ID toasted in the onCreate method on the intents activity.
Both times it prints "ID is: 1" even though both notifications are unique.
public class PossAffNotification{
private static int notif_ID = 1;
private static NotificationManager notificationManager;
private static Notification note;
private static PendingIntent contentIntent;
public static void sendAffimationNotice(Context ctx, String title,String contentText,int aff_id){
notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
note = new Notification(android.R.drawable.btn_star_big_on, contentText, System.currentTimeMillis() );
note.defaults |= Notification.DEFAULT_SOUND;
note.defaults |= Notification.DEFAULT_VIBRATE;
note.defaults |= Notification.FLAG_AUTO_CANCEL;
note.flags |= Notification.FLAG_AUTO_CANCEL;
Intent notificationIntent = new Intent(ctx, com.mindfsck.PossAff.MainActivity.class);
notificationIntent.putExtra("aff_id",aff_id);
System.out.println("putting " + aff_id);
notificationIntent.setAction("com.mindfsck.PossAff.intent.action.aff");
notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
contentIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
note.setLatestEventInfo(ctx, title, contentText, contentIntent);
notificationManager.notify(notif_ID,note);
notif_ID += 1;
}
};
public class MainActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Intent serviceIntent = new Intent(this,PAService.class);
this.startService(serviceIntent);
Bundle extras = getIntent().getExtras();
if(extras !=null) {
Toast.makeText(getApplicationContext(), "ID is: " + extras.getInt("aff_id"),
Toast.LENGTH_SHORT).show();
}
}
}
Your Intent is the same on all non-extra parameters (e.g., action). Hence, you get the same PendingIntent back from your getActivity() call, as there is only one PendingIntent per distinct Intent. You need to change something -- beyond extras -- in your second Intent, such as a different action string.
The problem for this issue came from this line:
contentIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
The last parameter shouldn't be 0 it should be PendingIntent.FLAG_CANCEL_CURRENT
contentIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
otherwise in notificationIntent you will receive same data all the time
This article of mine may be helpful here: "A pitfal in PendingIntent"
The issue basically comes from the fact, that the system does not assume that only because we pass a new Intent object to the pending intent, we want this new intent object to be delivered and just keeps the old (initial) pending intent alive.
To get the desired semantics, we need to pass a flag to tell the system:
PendingIntent pintent =
PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);

Categories

Resources