getLongExtra always return default value using PendingIntent - android

I want to pass a long value using a PendingIntent something like this
Intent intentForPending = new Intent(context, NewBlaBlaActivity.class);
long courseId = 15252;
intentForPending.putExtra("courseId", courseId);
intentForPending.putExtra("isFromPushNotification", true);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intentForPending, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context).setSmallIcon(R.drawable.appicon)
.setContentTitle("BlaBla")
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message)
.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
And get the value as below
Intent intent = getIntent();
if(intent.getBooleanExtra("isFromPushNotification", false)) {
long courseId = intent.getLongExtra("courseId", 0);
}
But I always get 0 from the intent. The weird thing is while I can get the boolean value with 'isFromPushNotification' key from the intent, I cannot get the long value from the same intent.
This drives me crazy. As you can see, it is a PushNotification and this code runs when I tap on the notification.
I tried all the way I can get from the forums and questions in stackoverflow, adding L suffix on def and original value on long objects. But I think PendingIntent is wet blanket.
I am waiting for your godlike advices. Thanks!

If you are going to use extras with a PendingIntent, always use a flag in the last parameter of the PendingIntent factory method (getActivity() in your case). Probably you want FLAG_UPDATE_CURRENT, to indicate to replace any existing PendingIntent contents with the new extras.

Related

Parcelable content not updating

I have a JSON message being sent to a listening service in my first Android app (read: pelase be gentle!) that is mapped to an object that implements Parcelable. The deserialized object is used to display a notification, with an intent that is meant to launch another activity displaying the full data in a layout.
Using the deserialized object I'm able to display the information in the notification without issue. The code in the notification to launch the secondary activity:
Intent intent = new Intent(this, SecondaryActivity.class);
intent.putExtra("objData", myObj);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setContentTitle(myObj.getTitle())
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(myObj.getAbstract()))
.setContentText(myObj.getAbstract());
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
In the SecondaryActivity I unwrap the parcel like so:
MyObject myObj = getIntent().getParcelableExtra("objData");
and use its data to fill in areas of the layout.
This works great on the first notification. On subsequent notifications, the notification looks correct but the parcelable data sent to SecondaryActivity is not updated (the content appears to the same as the first notification).
I'm assuming I'm missing something obvious that is preventing the parcelable object from being updated. Can you help?
When creating the pending intent you could try adding the flag FLAG_CANCEL_CURRENT or FLAG_UPDATE_CURRENT
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

Send Notification ID through to activity for each notfication

I am seriously confused now, I have been reading several SE examples and they all seem to be doing slightly different things.
What i want to do: Is have a single Activity called NotificationActivity, when I click on a notification it must open that activity and provide the activity with a DeviceId. I don't want to override or update any pending activities. Each activity should be its own intent.
There should only be once instance of NotificationActivity.
here is the code I have so far:
MyGcmListenerService:
Intent intent = new Intent(this, NotificationActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
//ADD My Extras
intent.putExtra(CommonBundleAttributes.CONNECTING_ACTIVITY_DEVICE_ID, content.DeviceId);
intent.putExtra(CommonBundleAttributes.CONNECTING_ACTIVITY_DEVICE_TYPE_ID, content.DeviceTypeId);
intent.putExtra(CommonBundleAttributes.CONNECTING_ACTIVITY_DEVICE_NAME, content.DeviceName);
//
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(content.DeviceName)
.setContentText("Notification")
.setAutoCancel(true)
.setSound(ingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setGroup("Mi:" + content.DeviceId)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NotificationID++, notificationBuilder.build());
and my NotificationActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
deviceId = getIntent().getExtras().getLong(CommonBundleAttributes.CONNECTING_ACTIVITY_DEVICE_ID, -1);
deviceName = getIntent().getExtras().getString(CommonBundleAttributes.CONNECTING_ACTIVITY_DEVICE_NAME, "");
deviceTypeId = getIntent().getExtras().getInt(CommonBundleAttributes.CONNECTING_ACTIVITY_DEVICE_TYPE_ID, 0);
What am I missing here/ I think I am getting mixed up with all the different flags and launcher types.
If there is already an NotificationActivty in memory, I want to close it and open a new one with the latest intent. If there are 3 notifications on the users phones, and they click on all three. it must open the NotificationActivty for the last clicked Notification.
There must be an issue with my pending intent?
In NotificationActivity, you collect int or long value using following code i.e.
notificationID = getIntent().getExtras().getInt(CommonBundleAttributes.CONNECTING_ACTIVITY_NOTIFICATIONID, 0);
then please pass a proper value with putExtra() i.e. if collect int then pass Integer.parseInt(content.DeviceId) or collect long then pass Long.parseLong(content.DeviceId)
hope it's helpful to you
In Notification class add this line
intent.putExtra(CommonBundleAttributes.CONNECTING_ACTIVITY_NOTIFICATIONID, NotificationID);
In NotificationActivity
notificationID = getIntent().getExtras().getInt(CommonBundleAttributes.CONNECTING_ACTIVITY_NOTIFICATIONID, 0);

Intent not delivered correctly

I am sending an Intent from GCMIntentService through PendingIntent. I am inserting some strings inside intent and in PendingIntent, I call an activity which will receive intent. But the data is not what I am sending. Here is the screenshot.
The first Intent shown is what I am sending, and the second is what I am receiving. Here is the code for sending:
Intent intent = new Intent(getBaseContext(),
Group_Chat_MainActivity.class);
intent.putExtra("group_id", group_id);
intent.putExtra("group_title", name);
intent.putExtra("from_push", true);
PendingIntent pendingIntent = PendingIntent.getActivity(
getBaseContext(), 100,
intent, 0);
Notification notification = new NotificationCompat.Builder(
getBaseContext()).setContentTitle("Paisa Swipe")
.setContentText(msg)
.setSmallIcon(R.drawable.home_logo)
.setTicker(ticker)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent)
.setAutoCancel(true).build();
notificationManager.notify(Integer.parseInt(group_id),
notification);
When I click notification, it sends to the Group_Chat_MainActivity class. In that, I use getIntent() to fetch the Intent data:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getIntent().getStringExtra("group_title")
getIntent().getStringExtra("group_id")
getIntent().getBooleanExtra("from_push",false)
}
Here I am getting different strings then what I sent. Any ideas?
Actually the problem is your PendingIntent requestCode is same all the time i.e 100. Keep it to be a unique for a group for eg. your group_id. Also your context here should be your GCMIntentService context.Try changing this to
PendingIntent pendingIntent = PendingIntent.getActivity(
getBaseContext(), 100,
intent, 0);
this
PendingIntent pendingIntent = PendingIntent.getActivity(
yourContextHere, Integer.parseInt(group_id),
intent, 0);
Make sure your getBaseContext() is not null.
If you use it in Fragmnet try:
inflatedview.getContext();
instead of:
getBaseContext()
and when you want get value from your intent in OnCreate method, try this:
getIntent().getExtras().getString();
instead of:
getIntent().getStringExtra();
hope this help you.

Android - Having trouble with calling a service from an action button of a notification

I want to be able to have a button that copies the text from a notification to the clipboard. The notification is sent through the google's GCM service.
The first time the notification arrives when I press the "copy" button everything is fine and the text goes into the clipboard by the service that the button sends an intent to. The second time a notification arrives with different text when I press the "copy" button the content of the first notification goes into the clipboard instead of the new one. When I debug the code, it seems that the intent that's calling the service has the new content, but the service that puts it into the clipboard runs with the parameters of the old notification, as if the same session of the service is awaken with the old intent.
Any clue why this is happening?
// Called by the GCM notification handler
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, MainActivity.class), 0);
Intent notificationIntent = new Intent(this, clipboardService.class);
notificationIntent.putExtra("tool",msg);
PendingIntent serviceIntent = PendingIntent.getService(this, 0, notificationIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_gcm)
.setContentTitle("Here's your text!")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.addAction(R.drawable.ic_stat_gcm, "Copy", serviceIntent); // <--- The intent will have the right (new) value on the second run
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
This is the service that the notification actions calls to:
public class clipboardService extends IntentService {
public clipboardService() {
super("clipboardService");
}
#Override
protected void onHandleIntent(Intent intent) { //This intent will have the values of the first intent to fire, instead of the updated one.
String msg = (String) intent.getExtras().get("tool");
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("2android",msg);
clipboard.setPrimaryClip(clip);
}
Although it is very late to answer your question, but recently I faced the same issue and Google led to me this unanswered question. So here is my understanding if in future someone dig this up.
This is because PendingIntent uses cached intent extras from previous instance of the intent unless you explicitly tell it not to. There are two ways to do that...
Use FLAG_CANCEL_CURRENT or FLAG_UPDATE_CURRENT (best in your case) as flag while constructing the PendingIntent. The first flag will automatically dismiss the previous PendingIntent and create a completely new one and the second one will only update the extras for the PendingIntent and save the overhead of creating a completely new one.
PendingIntent.getService(this, 0, notificationIntent,
FLAG_CANCEL_CURRENT | FLAG_UPDATE_CURRENT);
Pass an unique requestCode to the PendingIntent constructor everytime. This will generate unique pending intents for everytime so that you can access the extras associated with a particular intent later. I believe this is not required in your case.
PendingIntent.getService(this, UNIQUE_ID, pi, 0);

Editing notification object?

I have created the notification object using NotificationCompat.Builder and then elsewhere in my service I'd like to update value. What is the right approach to do this? Should I cancel this object and bulid another one?
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new NotificationCompat.Builder(this)
.setContentTitle("App")
.setContentText("estimated value:" + String.valueOf(value)) // <---- wanna update this
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendIntent)
.build();
startForeground(1235, noti);
You do not need to cancel your previous notification. Instead, you can simply run the identical code with different content text (in this case, changing value).
For more info, see the Updating Notifications section of the Android docs.

Categories

Resources