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();
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()
- 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
How to Style the Menu Items on an Android Action Bar
How to Change the Background of an Android Tab Widget
Android: Launch Activity from Clickable Text
Remove Bottomnavigationview Labels
How to Tell Which App Was Selected by Intent.Createchooser
Inserting Contacts in Android 2.2
Android Copy/Paste from Clipboard Manager
Uncaught Exception in Firebase Runloop (3.0.0)
Installation Error: Install_Failed_Older_Sdk
Android Xml VS Java Layouts Performance
How Do Task Managers Kill Apps
How to Merge Dex - Android Studio 3.0
I Have Forgotten My Keystore Password and I Want to Install My APK on Google Play. What Do I Do
Execution Failed for Task App:Transformclasseswithdesugarfordebug Error on Android Studio 3.0 Beta 2
Occured an Internal_Error When Requestemail from Googlesigninoptions Android
Android: How to Programmatically Set the Size of a Layout
Android Wifi How to Detect When Specific Wifi Connection Is Available