Reputation: 3593
I am trying to send information from notification to invoked activity, while from my activity I got null.
The code for notification is:
private void showNotification() {
Intent resultIntent = new Intent(this, MainActivity.class);
if (D)
Log.d(TAG, "Id: " + Id);
resultIntent.putExtra("ineedid", deviceId);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MeterActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
// Bundle tmp = resultIntent.getExtras();
// if (tmp == null) {
// Log.d(TAG, "tmp bundle is null");
// } else {
// long id = tmp.getLong("ineedid", -1);
// Log.d(TAG, "tmp id : " + id);
// }
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
BLEMessengerService.this)
.setSmallIcon(R.drawable.ic_action_search)
.setContentTitle("Event tracker")
.setContentText("Events received").setOngoing(true)
.setContentIntent(resultPendingIntent)
.setWhen(System.currentTimeMillis());
int mId = R.string.service_notification_start_service;
mNM.notify(mId, mBuilder.getNotification());
}
Code for get information from intent in main activity;
Bundle extras = getIntent().getExtras();
if (extras != null) {
long deviceID = getIntent().getLongExtra("ineedid",
-1);
if (ID == -1) {
if (D)
Log.i(TAG_D, "Wrong Id received.");
finish();
} else {
device = dataSource.getDeviceByID(deviceID);
if (D)
Log.i(TAG_D, "Get the id.");
}
} else {
if (D)
Log.d(TAG_D, "Bundle is null");
finish();
}
I have verified before the notification get notified, bundle is not null, and it has id in extras. While, when I tried to fetch it from intent, it's gone. Help.
Upvotes: 64
Views: 28237
Reputation: 2846
In Pending intent add this two flag
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
val yourDataIntent = Intent(mContext, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
putExtra("unique_id", "yourId")
putExtra("type", "yourType")
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context,
0,
yourDataIntent,
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE)
Upvotes: 3
Reputation: 652
For me, my Samsung device kept removing the extras from the intent and sometimes even crashed the app. Tried all the combinations but the actual reason for this behaviour was not explicitly adding PendingIntent.FLAG_IMMUTABLE
flag to the pending intent.
Although, this is a requirement for Android 12 and above.
val pendingIntent = PendingIntent.getActivity(
this, 0,
getIntent(),
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
Upvotes: 5
Reputation: 3351
If you are using the implicit intent to build a PendingIntent, you may get this problem.
previous approach with the issue.
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse("deeplink or applink here")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
intent.putExtra("key", Parcelable)
PendingIntent.getActivity(context, abs(Random.nextInt()), intent, PendingIntent.FLAG_UPDATE_CURRENT)
based on implicit Intent tried multiple approaches listed above not work for me.
here is the approach solved my problem. change the Intent from implicit one to an explicit one.
// only diff
val intent = Intent(context, YourIntentDestinationActivity::class.java)
// only diff
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse("deeplink or applink here")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
intent.putExtra("key", Parcelable)
PendingIntent.getActivity(context, abs(Random.nextInt()), intent, PendingIntent.FLAG_UPDATE_CURRENT)
hope this works for you.
Upvotes: 0
Reputation: 4297
When an activity is launched(when it is first started ) or relaunched(when it's brought to the top of the stack) the getIntent().getExtra()
won't give null
. But when the activity is present on the top of the stack then on starting that activity with the use of PendingIntent
would not relaunch the activity(onCreate()
won't get called) instead onResume()
would be called. And getIntent().getExtra()
would return the value which is associated with the intent that started the activity(which is null
).
In order to update the intent do the following steps:
1). Set FLAG_ACTIVITY_SINGLE_TOP
and FLAG_ACTIVITY_CLEAR_TOP
flags in your intent.
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2). Override onNewIntent()
in the activity where getIntent().getExtra()
is called. This method is called by FLAG_ACTIVITY_SINGLE_TOP
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
For more info: See this doc
Upvotes: 23
Reputation: 31
I was working in a local notifications plugin for Unity when I encountered the same problem -> I launched the app, scheduled the local notification, sent the app to background, local notification appeared and, when I clicked on it, app was resumed and getIntent().getExtras()
was null
.
In my case, the problem was I was trying to get the extras at the wrong intent. Try to print the intents with a simple toString, at the creation moment and when you get it, to ensure that the received is what you expect.
Also take a look to the onNewIntent method.
Upvotes: 1
Reputation: 1756
in PendingIntent use this flag PendingIntent.FLAG_UPDATE_CURRENT
it's work for me
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Upvotes: 67
Reputation: 12103
For me, in addition to setting Intent.FLAG_ACTIVITY_SINGLE_TOP , I had to add a unique action to the intent:
Intent resultIntent = new Intent(caller, NotificationActivity.class);
String xId = getNextUniqueId();
resultIntent.putExtra("x_id", xId);
resultIntent.setAction(xId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
.. without the setAction(..), Extras is null on the Intent received by my NotificationActivity.
This post helps explain it: https://stackoverflow.com/a/3128271/2162226
Upvotes: 38
Reputation: 3593
I just got the answer,
add line: resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
NOTICE: if you add it as resultIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
It won't work.
I also tried other flags like, "FLAG_ACTIVITY_NEW_TASK" and "FLAG_ACTIVITY_RESET_TASK_IF_NEEDED". neither works here.
Upvotes: 17