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);
Related
I have app which sends notifications, I used this code for pending intent
Intent myIntent = new Intent(getApplicationContext(),MainActivity.class);
myIntent.putExtra("link",Link);
PendingIntent intent2 =
PendingIntent.getActivity(getApplicationContext(),1,myIntent,
PendingIntent.FLAG_ONE_SHOT);
and it worked nice for the first time, but I use this piece of code inside a method that invokes every 1 minute.
The problem is that the link variable changes from one to another.
and when I get the data in the MainActivity I found the last link only, all the notifications created has the last link.
and I don't know how to avoid this.
You are sending the same request code for your pending intents. These codes are defined as the 2nd parameter of your Pending intent declaration
Change
PendingIntent intent2 =
PendingIntent.getActivity(getApplicationContext(),1,myIntent,
PendingIntent.FLAG_ONE_SHOT);
To:
PendingIntent intent2 =
PendingIntent.getActivity(getApplicationContext(),UNIQUE_INT_VALUE_FOR_EVERY_CALL,myIntent,
PendingIntent.FLAG_ONE_SHOT);
If you use the same id, the intent will be reused and you will only get the last data rather than getting new data for every call.
Try This,
PendingIntent contentIntent = PendingIntent.getActivity(GCMNotificationIntentService.this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
In Kotlin
Make a notification
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
For one and more just change the request Code number:
val pendingIntent = PendingIntent.getActivity(context,
System.currentTimeMillis().toInt(),intent, 0)
then
builder.setContentIntent(pendingIntent)
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.
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.
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);
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.