How to Correctly Pass Unique Extras to a Pending Intent

How can I correctly pass unique extras to a pending intent?

Possibly two different issues here:

1) If you've already created your PendingIntent before and it "matches" an existing PendingIntent, then you must specify the PendingIntent.FLAG_UPDATE_CURRENT flag or it will not pass the extras. A "match" is based on the criteria that Intent.filterEquals() uses, so definitely read the docs there and make sure you understand the data, action, type, etc.

2) I've read that if you do NOT set an action on your intent, then it will not propagate the extras, so perhaps try intent.setAction("com.blah.Action").

How can I correctly pass unique extras to a pending intent?

Possibly two different issues here:

1) If you've already created your PendingIntent before and it "matches" an existing PendingIntent, then you must specify the PendingIntent.FLAG_UPDATE_CURRENT flag or it will not pass the extras. A "match" is based on the criteria that Intent.filterEquals() uses, so definitely read the docs there and make sure you understand the data, action, type, etc.

2) I've read that if you do NOT set an action on your intent, then it will not propagate the extras, so perhaps try intent.setAction("com.blah.Action").

DP5 7.0 - Does adding extras to a pending intent fail?

For anyone ending up here pulling your hair out over AlarmManager (and haven't given up and gone to JobScheduler yet), Google in the production API 24 build does not support passing a Parcelable object into the AlarmManager.

The way I got around this:
If you need to send a List (or single object) into the AlarmManager, store the item into SharedPreferences as a String. (Gson.toJson(object, type)) If the object is an interface, there are a number of interface adapter solutions out there. One I found floating around S/O:

public final class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {

public JsonElement serialize(T object, Type interfaceType, JsonSerializationContext context) {
final JsonObject wrapper = new JsonObject();
wrapper.addProperty("type", object.getClass().getName());
wrapper.add("data", context.serialize(object));
return wrapper;
}

public T deserialize(JsonElement elem, Type interfaceType, JsonDeserializationContext context) throws JsonParseException {
final JsonObject wrapper = (JsonObject) elem;
final JsonElement typeName = get(wrapper, "type");
final JsonElement data = get(wrapper, "data");
final Type actualType = typeForName(typeName);
return context.deserialize(data, actualType);
}

private Type typeForName(final JsonElement typeElem) {
try {
return Class.forName(typeElem.getAsString());
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}

private JsonElement get(final JsonObject wrapper, String memberName) {
final JsonElement elem = wrapper.get(memberName);
if (elem == null)
throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper");
return elem;
}
}

Once you have the adapter set up, you won't need to set up GS0N each time with the TypeAdapter if you're using some sort of DI framework (i.e. Dagger2) like so...

@Singleton
@Provides
public Gson providesGson() {
return new GsonBuilder()
.registerTypeAdapter(YourInterfaceClass.class, new InterfaceAdapter<YourInterfaceClass>())
.create();

So all you'll have to do is run....

/**
* stores yourInterfaceClass in shared prefs
*/
public void setNextReminder(List<YourInterfaceClass> yourInterfaceClass) {
Type type = new TypeToken<List<YourInterfaceClass>>() {}.getType();
sharedPrefs.edit().putString(YOUR_KEY, gson.toJson(yourInterfaceClass, type)).apply();
}

Hope this helps. Of course, when you need to get this object out of shared prefs....

String json = sharedPrefs.getString(YOUR_KEY, "No object found");

Doing the typical List object = gson.fromJson(json, type) should work.

Cheers.

intent.putExtra() in pending intent not working

Try this

Intent aint = new Intent(getApplicationContext(), AlarmReceiver.class);
aint.putExtra("msg", msg);
aint.putExtra("phone", phone);

PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(),
id,
aint,
// as stated in the comments, this flag is important!
PendingIntent.FLAG_UPDATE_CURRENT);

Android sending extra's with pending Intent

fetch extras in your LoginActivity using intent extras as

    Intent intent = getIntent() ;
if(intent != null){
String fragment = intent.getStringExtra("fragment"); //if 'fragment' type is String (see other methods for appropriate type)
}

RecognizerIntent: how to add a bundle to a pending intent

These are my current answers to these questions. It works like this in a number of Google apps (Maps, Docs, YouTube, Listen) which all pass the PendingIntent to the RecognizerIntent when you perform the search via the microphone button. I am unsure though if this is the best (or most general) way of doing it. Any comments are welcome.

What is the best way of extracting a PendingIntent from a bundle?

Parcelable extraResultsPendingIntentAsParceable =
bundle.getParcelable(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT);
if (extraResultsPendingIntentAsParceable != null) {
if (extraResultsPendingIntentAsParceable instanceof PendingIntent) {
mExtraResultsPendingIntent =
(PendingIntent) extraResultsPendingIntentAsParceable;
} else {
// Report an error
}
}

mExtraResultsPendingIntentBundle =
bundle.getBundle(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE);

How to add extras to the set of existing extras of a PendingIntent?

Here we just create a new intent and put all the required extras into it.

if (mExtraResultsPendingIntentBundle == null) {
mExtraResultsPendingIntentBundle = new Bundle();
}
Intent intent = new Intent();
intent.putExtras(mExtraResultsPendingIntentBundle);
// Unsure about the following line...
// Should I use another name for the extra data (instead of SearchManager.QUERY)
intent.putExtra(SearchManager.QUERY, speechRecognitionResult);

How to launch the modified PendingIntent?

We send off the PendingIntent giving it the new intent (with the new extras) as an argument.

try {           
mExtraResultsPendingIntent.send(this, 1234, intent);
} catch (CanceledException e) {
// Handle exception
}

PendingIntent works correctly for the first notification but incorrectly for the rest

Don't use Intent.FLAG_ACTIVITY_NEW_TASK for PendingIntent.getActivity, use FLAG_ONE_SHOT instead


Copied from comments:

Then set some dummy action on the Intent, otherwise extras are dropped. For example

intent.setAction(Long.toString(System.currentTimeMillis()))

PendingIntent does not send Intent extras

Using PendingIntent.FLAG_CANCEL_CURRENT not a good solution because of inefficient use of memory. Instead use PendingIntent.FLAG_UPDATE_CURRENT.

Use also Intent.FLAG_ACTIVITY_SINGLE_TOP (the activity will not be launched if it is already running at the top of the history stack).

Intent resultIntent = new Intent(this, FragmentPagerSupportActivity.class).
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
resultIntent.putExtra(FragmentPagerSupportActivity.PAGE_NUMBER_KEY, pageNumber);

PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);

Then:

@Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);

int startPageNumber;
if ( savedInstanceState != null)
{
startPageNumber = savedInstanceState.getInt(PAGE_NUMBER_KEY);
//so on

It should work now.


If you still have not expected behaviour, try to implement void onNewIntent(Intent intent) event handler, that way you can access the new intent that was called for the activity (which is not the same as just calling getIntent(), this will always return the first Intent that launched your activity.

@Override
protected void onNewIntent(Intent intent) {
int startPageNumber;

if (intent != null) {
startPageNumber = intent.getExtras().getInt(PAGE_NUMBER_KEY);
} else {
startPageNumber = 0;
}
}

Notification passes old Intent Extras when the Activity that read the extras values is on top

using the answser of CommonsWare that helped with the override onNewIntetn and the link:
http://www.helloandroid.com/tutorials/communicating-between-running-activities

1 into xmlFile: put th android:launchMode="singleTask"
for the activity will receive the extra parameters with getExtras.

 <activity android:name=".ActivityWillReceiveWithGetExtras"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>

2.into the activity you that will receive the values with get_extras(...) override a method called onNewIntent:

2.1 Observation: put the line:

setIntent(intent);

to set the identifier of the intent.

   @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);//must store the new intent unless getIntent() will return the old one
getExtraParameterActual();

}

2.2 get the Extra parameters into a function that will have inside the command getExtras(...

 getExtraParameterActual();

  1. Write the function of the top getExtraParameterActual();

    private void getExtraParameterActual() {
    Intent intent = getIntent();//take back the value set with //setintenT of pass 2.1
    user = getIntent().getExtras().getString(USER);//
    }

5.
into OnCreate() call the e getExtraParameterActual();
and if necessary reload your views with a method for example reloadMyViews()


  1. into onResume() reload your views again with the same function of the pass 5 reloadMyViews()

7 the notificatio code I used take care with the FLAGS

 public void notificationCreateGu(String User) {

Log.d(TAG,nameOfTheService+"BUG createnotification for received CHAT messages useruidOfTheFriendNear="+newMessageUserUidOfSender);
Intent it = new Intent(this,ActivityWillReceiveWithGetExtras.class);
it.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
it.putExtra(USER,user);
StoreValuesClass.count=StoreValuesClass.count+2;
PendingIntent pi = PendingIntent.getActivity(this, StoreValuesClass.count,it, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this)
.setTicker(newMessageUserUidOfSender )
.setSmallIcon(android.R.mipmap.sym_def_app_icon)
.setContentTitle("Title Message ")
.setContentText(String.valueOf(newMessageUserUidOfSender))
.setContentIntent(pi)
.setAutoCancel(true)
.build();

int m;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
m= StoreValuesClass.count=StoreValuesClass.count+2;
notificationManager.notify((m), notification);

}


Related Topics



Leave a reply



Submit