Android. Can't clear or replace extras - android

I lunch activity from notification.
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP );
notificationIntent.putExtra(GCM_EXTRA_ID, id);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notificationManager.notify(0, notification);
If activity destroyed, intent creates new activity and call in oncreate activity this code
Bundle extras = getIntent().getExtras();
if(extras != null){
if(extras.containsKey(GCMIntentService.GCM_EXTRA_ID))
{
int id = extras.getInt(GCMIntentService.GCM_EXTRA_ID);
Toast.makeText(this, "GCM_EXTRA_ID ACTIVITY ON CREATE:" + Integer.toString(id) , Toast.LENGTH_LONG).show();
dbClassItem = new DBClass(this);
db = dbClassItem.getWritableDatabase();
DBClass.setLocateValue(db, id);
db.close();
getIntent().putExtra(GCMIntentService.GCM_EXTRA_ID, 0);
}
}
If I close activity by back button and start activity again application still see, that intent has extra with key GCMIntentService.GCM_EXTRA_ID (this is a public static string).
How can I clear or replace this extra for next app start. getIntent().removeExtra(), getIntent().getExtras().clear(),getIntent().putExtra(GCMIntentService.GCM_EXTRA_ID, 0) does not work. What can I do ? Activity has android:launchMode ="singleTop" key.

This problem was solved by using onNewIntent instead of using onCrete in Activity.

You can do this
notificationIntent.putExtra(GCM_EXTRA_ID, null);

Related

how to know if the app was launched by clicking on the push notification

I want to know if there is a flag and parameter that can tell me if the user launched the activity/app by clicking on the push notification in the notification tray.
My code in C2DMReceiver.java
Context context = getApplicationContext();
PackageManager manager = context.getPackageManager();
Intent notificationIntent = manager
.getLaunchIntentForPackage(packageName);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
**notificationIntent.putExtra("fromRemote", true);**
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification();
notification.icon = R.drawable.icon;
notification.tickerText = message;
notification.number = badge;
notification.when = System.currentTimeMillis();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_ALL;
notification.setLatestEventInfo(context, "Draw Something", message,
pendingIntent);
notification.contentIntent = pendingIntent;
notificationManager.notify(0, notification);
I tried setting
notificationIntent.putExtra("fromRemote", true);
but when the app was launched there were no extras in the intent.
my code in the onCreate function of my mainactivity
Bundle extras = getIntent().getExtras();
if (extras != null) {
print("onCreate - bundle has extras");
for (String key: extras.keySet())
{
Log.v ("mytag", "MainActivity onCreate key =" + key);
}
}
else {
Log.v ("mytag", "onCreate - bundle has NO extras");
}
The output i get is onCreate - bundle has NO extras. So the extras are not getting passed through.
So is there any other way?? It is so easy in iOS
Just posting an answer so that people who visit this page get the solution.
You need to use putExtra(ID_KEY,id) when you create your Intent for starting your application, and in your onCreate() method you can use getIntent().getExtras().getInt(ID_KEY); to retrieve your passed id integer.
The passed extra could be anything, a boolean, String etc.
Source - https://stackoverflow.com/a/7358692/3036759

PendingIntent does not send Intent extras

My MainActicity starts RefreshService with a Intent which has a boolean extra called isNextWeek.
My RefreshService makes a Notification which starts my MainActivity when the user clicks on it.
this looks like this:
Log.d("Refresh", "RefreshService got: isNextWeek: " + String.valueOf(isNextWeek));
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);
Log.d("Refresh", "RefreshService put in Intent: isNextWeek: " + String.valueOf(notificationIntent.getBooleanExtra(MainActivity.IS_NEXT_WEEK,false)));
pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
builder = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText("ContentText").setSmallIcon(R.drawable.ic_notification).setContentIntent(pendingIntent);
notification = builder.build();
// Hide the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(NOTIFICATION_REFRESH, notification);
As you can see the notificationIntent should have the booleanextra IS_NEXT_WEEK with the value of isNextWeek which is put in the PendingIntent.
When I click now this Notification I always get false as value of isNextWeek
This is the way I get the value in the MainActivity:
isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);
Log:
08-04 00:19:32.500 13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity sent: isNextWeek: true
08-04 00:19:32.510 13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService got: isNextWeek: true
08-04 00:19:32.510 13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService put in Intent: isNextWeek: true
08-04 00:19:41.990 13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity.onCreate got: isNextWeek: false
When I directly start the MainActivity with an Intent with the ìsNextValue` like this:
Intent i = new Intent(this, MainActivity.class);
i.putExtra(IS_NEXT_WEEK, isNextWeek);
finish();
startActivity(i);
everything works fine and I get true when isNextWeek is true.
What do I make wrong that there is always a false value?
UPDATE
this solves the problem:
https://stackoverflow.com/a/18049676/2180161
Quote:
My suspicion is that, since the only thing changing in the Intent is
the extras, the PendingIntent.getActivity(...) factory method is
simply re-using the old intent as an optimization.
In RefreshService, try:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
See:
http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_CANCEL_CURRENT
UPDATE 2
See answer below why it is better to use PendingIntent.FLAG_UPDATE_CURRENT.
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;
}
}
I think you need to update the Intent when you receive a new one by overriding onNewIntent(Intent) in your Activity. Add the following to your Activity:
#Override
public void onNewIntent(Intent newIntent) {
this.setIntent(newIntent);
// Now getIntent() returns the updated Intent
isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);
}
Edit:
This is needed only if your Activity has already been started when the intent is received. If your activity is started (and not just resumed) by the intent, then the problem is elsewhere and my suggestion may not fix it.
Following code should work:-
int icon = R.drawable.icon;
String message = "hello";
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("isNexWeek", true);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
In MainActivity onCreate:
if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
So the actual reason is that the PendingIntent will cache the previous intent if the intents only differ in their extras. In my situation no combination of PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_CANCEL_CURRENT solves this as either the old intent will be replaced or the new one will stay the same as the initial one.
You need to ensure that Android cannot cache the Intents behind the PendingIntent. The solution for me is to make them differ in their data attribute.
so in the original posters code you would need to ensure that the data attribute is unique per each combination of extras that you are attaching.
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);
notificationIntent.setData(Uri.parse("myapp://nextWeek/" + (isNextWeek ? "1" : "0"))
Alternatively you could probably also just add a uuid to the data uri (however, if you have lots and lots of notifications, it might be nice to cache them

How to Pass data with Notification to Main Activity

Am using phonegap 2.5.0 for my android app. In this am enabling notification with intent. The intent having some extra data. The notification code is below,
Notification notification = new Notification(icon, contentTitle, when);
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra("notificationType", "updateAvailable");
notificationIntent.putExtra("updateUrl", updateUrl);
notificationIntent.putExtra("updateVersion", updateVersion);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestID = (int) System.currentTimeMillis();
PendingIntent contentIntent = PendingIntent.getActivity(this, requestID, notificationIntent, 0);
//PendingIntent contentIntent = PendingIntent.getActivity(this, requestID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, contentTitle, contentText, contentIntent);
NotificationManager nm = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, notification);
The above generated notification calling the mainactivity of the android app. The MainActivity script is below,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String notificationType = intent.getStringExtra("notificationType");
if(extras != null)
{
if(extras.getString("notificationType").equals("updateAvailable"))
{
String updateUrl = extras.getString("updateUrl");
String updateVersion = extras.getString("updateVersion");
super.loadUrl("file:///android_asset/www/update.html?updateVersion="+updateVersion+"&updateUrl="+updateUrl);
}else
startMyApp();
}else
{
startMyApp();
}
}
The startMyApp function having code to start application (only called while opening the application directly using application icon).
But the code not working. Application not working (i.e application not opened on clicking the application icon) Unfortunately stopped Application error displayed and application was closed. If am removing intent receiving contents from oncreate function and if only the startMyApp() function called from onCreate application started successfully.
Help me to pass data with notification to MainActivity. The startMyApp()'s code is below
public void startMyApp()
{
super.loadUrl("file:///android_asset/www/dashboard.html");
}
super.loadUrl("file:///android_asset/www/update.html?updateVersion="+updateVersion+"&updateUrl="+updateUrl);
This will not work, since it will search for a file named update.html?updateVersion=xxx&updateUrl=xxx and not update.html.

Unable to get extras from an intent which is called using notification's pending intent?

Below i am having code for two notifications and in intent i am passing extras with key1 and key2 but in NotificationPillDescription.class i am only able to get key1 using getExtras.
// Notification Code For First Notification
Notification notification = new Notification(R.drawable.ic_launcher, "Take your morning pill!", System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notifyIntent = new Intent(getApplicationContext(), NotificationPillDescription.class);
Bundle extras = new Bundle();
extras.putString("Key1", String.valueOf(1));
notifyIntent.putExtras(extras);
contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notifyIntent, 0);
notification.setLatestEventInfo(this, "Take your Morning pill!", "My Drug", contentIntent);
notificationManager.notify(dataProvider.notificationId++, notification);
// Notification Code For Second Notification
notifyIntent = new Intent(getApplicationContext(), NotificationPillDescription.class);
Bundle extras = new Bundle();
extras.putString("Key2", String.valueOf(2));
notifyIntent.putExtras(extras);
contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notifyIntent, 0);
notification.setLatestEventInfo(this, "Take your Morning pill!", "My Drug", contentIntent);
notificationManager.notify(dataProvider.notificationId++, notification);
//Code for NotificationPillDescription.class
Bundle extras = getIntent().getExtras();
if(extras != null){
if(extras.containsKey(String.valueOf(1)))
{
Log.d("Pill Id0",extras.getString(String.valueOf(1)) );
}
else
{
Log.d("Pill Id1",extras.getString(String.valueOf(2)) );
}
}
It should be,
extras.getString("Key1") and extras.getString("Key2")
instead of
extras.getString(String.valueOf(1)) && extras.getString(String.valueOf(2))
Have a look here. It describes how to pass a bundle. I think your extras.getstring might not be enough. you might also not need to declare a bundle if you're using putextras.
Here:
Passing a Bundle on startActivity()?
This might be helpful too:
putExtras multiple putString not working

Android Status Bar Notifications - Intent getting the old extras on the second time

When I create a notification that is sent through C2DM and received in my app I want to pass some of the data that came with the push notification from C2DM in the intent extras. This works fine the first time I open my notification. Then the data is received with onNewIntent or in onCreate depending on the state of the activity.
But if I send a second push notification through C2DM it is received correctly with the new data but when getting the extras from the intent I still get the data from the previous message. The title and the data I want to see is shown correctly in the notification. So something must be wrong the my intent. This happens if the activity is running and if it isn't.
To create the notification I do the following:
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_stat_notify_push, "Message received", System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notification.defaults |= Notification.DEFAULT_LIGHTS;
Intent intent = new Intent(context, DesktopApp.class);
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("msg_id", msg_id);
intent.putExtra("title", title);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
notification.setLatestEventInfo(context, "New message", title + String.valueOf(msg_id), pendingIntent);
notificationManager.notify(0, notification);
To then read the intents:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent myIntent = getIntent(); // this is just for example purpose
int i = myIntent.getIntExtra("msg_id", -1);
if (i != -1) Toast.makeText(this, "Got message! " + String.valueOf(i), Toast.LENGTH_LONG).show();
}
#Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
Bundle extras = intent.getExtras();
if (extras != null) {
int i = extras.getInt("msg_id", -1);
if (i != -1) Toast.makeText(this, "Got message! " + String.valueOf(i), Toast.LENGTH_LONG).show();
}
}
Any suggestions?
You need to set up a clean flag to PendingIntent:
PendingIntent pintent =
PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);
Have a look at this post that gives a longer explanation.
Use this
PendingIntent pi = PendingIntent.getActivity(context, UNIQUE_ID,
intent, PendingIntent.FLAG_UPDATE_CURRENT);

Categories

Resources