I have been struggling with this problem for a while now. I have a widget which displays summary of a cooking recipe. The widget is clickable so whenever user clicks on it the new activity is opened with a full description of that recipe. The problem is that sometimes when the widget is clicked it opens a wrong activity. Let me give you an example:
User clicks on widget and activity A is opened
User starts activity B (e.g. recipe index) from the activity A.
User starts activity C from activity B.
User presses Home button.
User clicks on the widget again and the activity C is displayed instead of A
I tried setting a compibation of those three flags which helps in solving only a half of the problem:
openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
By using above flags I managed to display a correct activity (A) until I do the following:
User opens activity A from the widget
User moves to activity B and opens activity A by clicking on new recipe
New recipe is displayed to the user
User clicks Home button and clicks on the widget.
Activity A is displayed (the right one) but with different recipe.
From now on if I move to different activities B or C and click Home and then widget again the activity A is not displayed but the one which was visible before pressing Home button.
I hope I explained it in enough details. I would be really grateful for your help because this thing drives me crazy!
Updated:
This is my pendingIntent:
Intent openIntent = new Intent(context, ProfanityDefinition.class);
openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
openIntent.setData(Uri.parse(openIntent.toUri(Intent.URI_INTENT_SCHEME)));
Bundle bundle = new Bundle();
bundle.putBoolean("widgetRequest", true);
openIntent.putExtras(bundle);
PendingIntent openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_content, openPendingIntent);
Thanks
Show the code for creating the PedningIntent. If you are passing extras to your activity, be aware that two intents that differ only by extras are treated as equivalent. You probably want to pass the PendingIntent.FLAG_CANCEL_CURRENT when you create the PendingIntent to make sure your intent is not reused.
Related
I have working with widgets which helpfull the user to show important data and open the application from widget.
My widget has 3 buttons and i need to open the app when user click on the different buttons.
i need to open same activity but with different data based on which button user clicked. I have passing different extra with intent
for example
Ist button i set user name as "Ranjith"
and for 2nd button i set user name as "Thomas"
and for 3rd button "Rixon"
But when the activity open it always shows Rixon the third one.
logIntent= new Intent(context, MainActivity.class);
earnIntent=new Intent(context, MainActivity.class);
connectIntent=new Intent(context, MainActivity.class);
logIntent.putExtra("user_name", "Ranjith");
connectIntent.putExtra("user_name", "Thomas");
earnIntent.putExtra("user_name", "Rixon");
}
remoteViews.setOnClickPendingIntent(R.id.bottom_of_widget_log,createPendingIntent(context, 0, logIntent));
remoteViews.setOnClickPendingIntent(R.id.bottom_of_widget_earn, createPendingIntent(context, 1, earnIntent));
remoteViews.setOnClickPendingIntent(R.id.bottom_of_widget_connect, createPendingIntent(context, 2, connectIntent));
AppWidgetManager manager = AppWidgetManager.getInstance(context) ;
manager .updateAppWidget(thisWidget, remoteViews);
You have to check the android:launchMode option in your Manifest,concerning the Activity.
As said in the Documentation,
An activity with the "standard" or "singleTop" launch mode can be instantiated multiple times[....]
In contrast, "singleTask" and "singleInstance" activities can only begin a task. They are always at the root of the activity stack. Moreover, the device can hold only one instance of the activity at a time — only one such task.
I have appwidget with listview. Some information we can see here
1) This widget don't worked on 2.x. But user on this devices see this widget at his list and can move it at screen. After he get error. Can I any way to hide this widget on 2.x? Ofcouse, I can set title for this widget as "MyWidget... (3.x-4.x). But I think this is not good.
2) Second issue. On click widget I open my application one activity (widgetAct). This is not main activity. widgetAct showed as dialog. All works, but... If I open main activity, next click HOME, not BACK. Now click on widget, opened my widgetAct, but on background I see also main activity.
3) Another case. Open widgetAct. See this activity. Click BACK. Now long press: see last started application. Click on my application (which contain widgetAct) and see this widgetAct. But want see main activity or any another activity my application, but not widgetAct.
I try different cases: add FLAG_ACTIVITY_NO_HISTORY, FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP. But nothing help:
Intent i = new Intent(ctx, myActivityCls); i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pi = PendingIntent.getActivity(ctx, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(viewId, pi);
I see, that my widgetAct on open have only FLAG_ACTIVITY_NEW_TASK flag.
I don't know why, but... I set some flags to intent and start activity on click widget. Really opened activity have only FLAG_ACTIVITY_NEW_TASK.
Solutions:
1) Move widget xml provider from xml folder to xml-v11. Now on 2.x devices this widget is hided.
2) Second case: set for widgetAct taskAffinity. But in this case at recent apps I see 2 my application instances, because used 2 stack activities. To fix it add to widgetAct:
#Override
protected void onPause() {
super.onPause();
finish();
}
3) On click at widget open widgetAct. I close this instance widgetAct and open another widgetAct, but add next flags: FLAG_ACTIVITY_NO_HISTORY, FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.
I am developing an application and its Home Screen Widget.
Now from my widget when i press on a button it would open up my application from where it was left.
Means if i press home button during my application running then my application will go in background mode.
Now i want that it should resume my opened application.
Whenever i press a button from my Widget. How Can i Do it??
Please help
Thanks a bunch in advance!
I've never made a widget before, but this is how I've made a notification launch back into my original activity when you pull down the bar and click it.
Intent originalActivity = new Intent(getApplicationContext(), Widget.class);
originalActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Once again, not sure how you would do this with a widget, but to relaunch it for a notification you convert that Intent into a PendingIntent to be called later when you want to launch back into it. I would assume this is a similar fashion for how you would it on a widget.
I've got an Android App Widget that when clicked uses a PendingIntent to start an Activity, which the main Application associated with the App Widget also uses. After the user is done with the Activity started from the App Widget, and presses the back button, the user is taken to the Activity on the top of the MAIN application Activity stack. I'd like the back button to take the user back to the Android desktop/home screen.
In short, I'd like separate Activity stacks for my App Widget and Application. Not sure why Android wants to combine these.
This is what I've got now in the App Widget and it's not working. Neither Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK seems to have any impact on the stack.
Intent intent = buildWidgetIntent(context, info);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context,
mRequestCode++, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Thanks for any help with this one.
I haven't faced this exact situation, but Intent.FLAG_ACTIVITY_NO_HISTORY is what I needed to make my widget-launched Activity always go Back to the Home screen.
I know, there are several questions of this type but I tried all of it and it still doesn't work.
Ok, for my app; I've got an Activity. In this Activity, there are 4 Tabs, and the fourth one contents a list and a record button. When I am pushing record, there is a GPS Listener which starts. After getting a new gps value, it pushes it into the list.
This works so far!
If I click the Home Button it still works, if I longpress it then. It resumes that Activity with the specific Tab open and the list still hold the listitems and the gps listener is still active.
This works also fine!
Now I wanted to add a notification, which shows the count of gps values of the list as .number. On every new gps signal, it updates the notification icon with the new number. This is no problem, but the action to click on the notification totally screws up my application.
The actual code looks like this:
public void callNotify(String text) {
notif = new Notification();
Intent contentIntent = new Intent(this, tabactivity.class);
contentIntent.putExtra("fid", this.specialvalue);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
notif.icon = R.drawable.icon;
notif.setLatestEventInfo(this, getString(R.string.app_name), text,
PendingIntent.getActivity(this.getBaseContext(), 0, contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
notif.ledARGB = Color.RED;
notif.ledOnMS = 200;
notif.ledOffMS = 200;
notif.flags = Notification.FLAG_SHOW_LIGHTS
| Notification.FLAG_ONGOING_EVENT
| Notification.FLAG_ONLY_ALERT_ONCE;
notif.number = notifyNumber;
mNotificationManager.notify(notifyNumber, notif);
}
public void updateNotify(String text) {
notifyNumber++;
notif.number = (int) (notifyNumber / 2);
Intent contentIntent = new Intent(this, tabactivity.class);
contentIntent.putExtra("fid", this.specialvalue);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
notif.setLatestEventInfo(this, getString(R.string.app_name), text,
PendingIntent.getActivity(this.getBaseContext(), 0, contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
mNotificationManager.cancel((notifyNumber - 2));
mNotificationManager.notify(notifyNumber, notif);
}
So, the updateNotify() is called on a new gps signal. And the callNotify() is the first one, before it starts the gps listener. And, yeah, the notifyNumber/2 was my intention, because I work with that number further.
If I compile it like this, and click on the Notification, it opens a NEW tabactivity on the first tab. If I click back then, I get a lot of errors (database is still open, nullpointers and stuff). I think because it starts a new tabactivity and the other one is still open, 'cause I can see the gps listener is still working.
So, what I want is, that I can do the following:
I open my app, go to the tabactivity, open tab 4, click record. If I click back then, it should hide the app, also, if I just click the home button. But there is a notification.
If I click on that one, it should just show the hidden activity again and thats it.
So, what I am doing wrong there?
I thought, the Flags FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP should solve the problem?
What is happening here is a little confusing so bear with me here.
FLAG_ACTIVITY_SINGLE_TOP according to the docs If set, the activity will not be launched if it is already running at the top of the history stack. So if the current activity is not at the top of the history stack it will be relaunched.
FLAG_ACTIVITY_CLEAR_TOP again from the docs If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
By default the TabActivity will always open to tab 0, you can use setDefaultTab to change that via code. Each Tab in the TabHost is also a new Intent
If I compile it like this, and click
on the Notification, it opens a NEW
tabactivity on the first tab. If I
click back then, I get alot of errors
(database is still open, nullpointers
and stuff).
This is happening I think because the current Intent is tab4 (in reality its #3, 0,1,2,3) and your notification is bringing up the tabactivity.class. Since it is not active or on top of the stack, every act on top of it is closed, including tab4.
So, what I want is, that I can do the
following: I open my app, go to the
tabactivity, open tab 4, click record.
If I click back then, it should hide
the app, also, if I just click the
home button. But there is a
notification. If I click on that one,
it should just show the hidden
acitivity again and thats it. So, what
I am doing wrong there? I thought, the
Flags FLAG_ACTIVITY_CLEAR_TOP and
FLAG_ACTIVITY_SINGLE_TOP should solve
the problem?
You are confusing what the flags do and what happens with the home and back keys. Hitting home will hide your activity and the notification should work fine with those flags (once you fix the problem I mentioned earlier). When you hit back though, Android ends the current Activity and takes it off the stack. Since there is nothing under it, you are forced to relaunch from scratch when you press the notification.