Appwidget with collection. Illegal working - android

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.

Related

Android: Launch new instance of application activity from home screen widget

I have an app widget on the home screen which includes a button that launches a basic settings Activity.
When the user presses the Back button, if the main application has some activities in it's stack, the back press takes you to the most recently viewed Activity in the app, rather than back to the homepage. I've tried the following flags for my intent:
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
But no luck with any. Is there any flag or combination of flags I can use to do this? Thanks.
You need to do the following:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
You are currently using setFlags which overrides the flags you set previously when you need both of these flags for it to work correctly.
You can read abut this at http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
try next
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
This flags run activity in new task and don't add it to history after exit.
So your settings activity don't cross with main app

Android AppWidget Configuration - Start in new task

I've searched and searched and searched for this!
So I've got an app widget and it has a configuration activity that I can open when pressing a button on the app. The scenario is:
Had the app opened.
Closed the app with the home button.
Selected to add my widget
I have configured the widget.
Placed on my home screen
Then open the configuration activity again with the button on the widget.
Cancel the new config by pressing back will put me back into the app.
When pressing back I want to just return home.
Basically what I'm asking is. How do I start the configuration activity in it's own task/stack?
I've looked into intent filters but I'm just not quite sure, or maybe it's something to do with the package it's in, or maybe it's just not possible!
I suppose it may have something to do with the intent I use to launch the config activity
Intent configIntent = new Intent(this, Configuration.class);
configIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
remoteView.setOnClickPendingIntent(R.id.config, PendingIntent.getActivity(this, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Perhaps because I launch it with 'this' as the context, it will always start in my applications stack...
but the pending intent api is:
PendingIntent API 1
"Note that the activity will be started outside of the context of an existing activity"
So yeah I'll stop talking now as I just end up going in circles!
EDIT
So tried android:launchMode="singleInstance" in the manifest like was stated. This worked however it stops the 'startActivityForResult' behaviour working correctly. (which is the whole reason for a config activity) Get the error:
WARN/ActivityManager(59): Activity is launching as a new task, so cancelling activity result.
So still haven't found a solution.
Ok sorted it :-) needed:
android:taskAffinity=""
in the manifest, setting the task affinity to an empty string allows for the activity to start in it's own stack, as it is not 'affiliated' with the rest of the application.
UPDATE
I have changed the task affinity to:
android:taskAffinity="com.my.package.alternative.task"
as each time I launched the activity it was showing up multiple times in the 'history'. So it now starts in it's own stack but is shared with other instances of the same activity.
Also need to add the Flag Intent.FLAG_ACTIVITY_NO_HISTORY to your intent :-) this stops your getting your application multiple time's in the history when you 'press and hold' the home button.
UPDATE
I've noticed FLAG_ACTIVITY_NO_HISTORY wasn't doing what I wanted, I've removed it and added:
android:excludeFromRecents="true"
into the activity tag in the manifest as well. The activity now behaves like I want :-)
Got this answer from the following link trail:
Tasks & Back Stack |
Managing Tasks |
Affiliation Tag
Try to put android:launchMode="singleInstance" for an activity of the app in AndroidManifest.xml

How do you separate an Android App Widget Activity stack from the Application Activity stack?

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.

Android - When launch the same activity from widget with different extras, how to prevent the same instance show up after returned from HOME button?

I have a widget that contains 4 buttons to show 4 stock prices, each of them will launch into the same activity Quote.class to show stock details. In onUpdate(), it will set up the pendingIntent with extras with stock symbol. After I hit button A, it goes to Quote activity that shows stock A. Then I hit the BACK button to the homescreen, Quote activity calls onDestroy() and when I hit button B, stock B will show properly. However, when i hit HOME button after it shows stock A, the Quote activity only calls onStop without calling onDestroy(), then as i hit button B, it will call onStart() and it shows the same instance that shows stock A.
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.etappwidget);
setQuoteIntent(context, views, R.id.view1, "BAC", 1);
setQuoteIntent(context, views, R.id.view2, "C", 2);
setQuoteIntent(context, views, R.id.view3, "GOOG", 3);
setQuoteIntent(context, views, R.id.view4, "AAPL", 4);
private static void setQuoteIntent(Context context, RemoteViews views, int viewId, String symbol, int requestCode) {
Intent i = new Intent(context, Quote.class);
i.putExtra("SYMBOL", symbol);
i.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
PendingIntent pi = PendingIntent.getActivity(context, requestCode, i, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(viewId, pi);
}
Originally I thought adding a flag in the Intent should solve this problem. But I have tried
i.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK or FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_NO_HISTORY), none of them makes any difference.
So is there any ways to make it work? How can i remove the history stack from HOME button? How can I call onCreate in Quote activity and get new extras when i hit button B? Any help is appreciated. Thanks
It is normal for onDestroy to possibly not get called if you do simple task switching (like holding the HOME button). If you need to do clean-up, it needs to go in onPause.
I believe the problem is that you have a PendingIntent that only differs by extra. PendingIntents are cached, so if you use two with the same action and data, they'll overwrite each other. You can circumvent that by giving each some random data. Try passing the symbol in the data rather than through the extra (which is preferred anyway).
You can try this:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Your activity will not be seen in the history stack
clickIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Since: API Level 1 If set, the new activity is not kept in the
history stack. As soon as the user navigates away from it, the
activity is finished. This may also be set with the noHistory
attribute.
This solved the same issue of mine while implementing widget activities.
When you press home, most probably the activity will not be destroyed. It is put to pause state in such case. So, I guess your code to initiate the stock view would stationed in onCreate rather than onResume. So, moving those to onResume should solve the problem.
If you are using a different Action in your Intent and use the SingleTop or similar flag and override onNewIntent to detect the correct action that should do the trick. You need to be prepared to handle the intent in onCreate and onNewIntent.

Notification Resume Activity

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.

Categories

Resources