Multiple widgets: Launching configuration activity on widget click - android

following scenario:
I have 3 of the same widgets on my home screen. If one gets clicked, the widget configuration activity gets launched.
This was implemented by following code:
Intent intent = new Intent(context, WidgetConfigurator.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setOnClickPendingIntent(R.id.widget_linearlayout, pendIntent);
The launching is working, but there is one problem:
1. Widget A gets clicked, configuration activity of Widget A is opened
2. User hits "back" key, configuration activity disappears
3. Widget B gets clicked, configuration activity of Widget B is opened
4. User hits "back" key
=> Now the configuration activity of Widget A is shown
I always only want the "actual" configuration activity (fitting to the widget that was clicked) to be shown. Which settings do i have to use for the Intent / PendingIntent?
thx for any help

Seems after trying around a lot i now found a working solution for all android versions:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setOnClickPendingIntent(R.id.widget_linearlayout, pendIntent);

Change your pending intent code to include the widget id as android reuses intents. I wasted many hours on this with the wrong intent being sent on click.
PendingIntent pendIntent = PendingIntent.getActivity(context, WIDGETID, intent, PendingIntent.FLAG_UPDATE_CURRENT);

A way to get sure your current activity gets closed is to call finish(). An android app is build like stack, the activity A starts, if the user hits back, this activity isn´t closing. It´s just lying under the new started activity B. If user hits back in activity B, then activity A will be shown. I never tried this, but if You call finish in your onBackPressed method, the current activity will be closed. To do this, override onBackPressed in your Activitys.

Related

Resume current activity or create another one from notification

I have two activities in my app.
The first one, which is login (the one which is started as Main/Launcher)
The second one, which contains fragments and so the main content. So Login activity starts Main activity.
When I receive a notification and click on it, I want to be able to handle those scenarios:
resume app if it's in background (like user resume it like pressing home key) but without showing the launcher activity (login).
launch app if it's not launched yet.
I tried with mode singleTask for both in Manifest and here the code in my service:
Intent intent = new Intent(this, MainActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pendingIntent = PendingIntent.getActivity(this, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Then I pass pendingIntent in the setContentIntent method of the notification.
But when I click on the notification, and the app is already launched and in background, it restarts the Login activity (I don't want it) but resume the Main activity correctly.

Resume activity from a android tv recommendation

I have some troubles with the management of recommendations (notifications) on an Android TV with the Leanback Launcher.
I use the google sample here to implement my own : https://github.com/googlesamples/androidtv-Leanback
Expected result :
I'm on my activity "MainActivity" (with a webview)
I press HOME, so I'm on the Leanback launcher with recommendation include mines.
I press on one of them
Resume activity "MainActivity" without recreate it with a new Intent with a new extra.
Actually, The resume of the activity without reload the activity works fine, below the creation of the PendingIntent :
private PendingIntent buildPendingIntent(Parcelable media, int id) {
Intent detailsIntent = new Intent(this, MainActivity.class);
detailsIntent.putExtra("media", media);
detailsIntent.putExtra("id", id);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(detailsIntent);
return stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
}
Current result :
I'm on my activity "MainActivity" (with a webview)
I press HOME, so I'm on the Leanback launcher with recommendation include mines.
I press on one of them
My activity receive "onNewIntent" event by in the extrat intent values I have always the same media.
This solution doesn't work, because Google said in a comment of the sample code :
// Ensure a unique PendingIntents, otherwise all recommendations end up with the same
// PendingIntent
detailsIntent.setAction(movie.getId());
So to differentiate all recommandations, I have to set Action with an ID, else, it will be always the last pendingintent sent to my activity. It's my current behavior, I receive in "onNewIntent" always the same "media" and "id" in the intent (the last one), whatever on which recommendation I click, I always get the same Intent.
But if I set the action with an "id", the activity "MainActivity" is recreated, so the resume failed, and the context of my webview is cleared my webview is reloaded :( but I get the good intent with the good media in the extra intent values.
Have you a solution to help me to have the behavior I want ?
To simplify my question, how can I resume my Activity B from a recommendation with the good pendingintent without reload my activity ?
Thank you in advance for your help.
I found a solution. I don't think it's the good one but it works for my case.
PendingIntent pIntent = PendingIntent.getActivity(this, id, detailsIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return pIntent;
So, If I set the "resquetCode" with the id, so Android think it's a different Activity and resume it without recreate a new one.

Activity flags / launchmode / pendingintent

i read a lot on the android documentation about launchmode and activity flags but i can't figgure it out.
i'm using the following code to open my activity from nothification:
Intent intent = new Intent(context, home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(context, NOTIFICATION_ID++, intent, PendingIntent.FLAG_UPDATE_CURRENT);
in the manifest i declared my home activity as
android:launchMode="singleInstance"
all works fine except for when i close my app (not only in background) only the
onstart method gets called but not the oncreate and i have no idea why?!
i need the following:
app is open and visible to the user: user click on nothification, the existing HOME activity get active and the onnewintent gets calls (works fine)
app is in background (user pressed home button):: user click on nothification, the existing HOME activity get active and the onnewintent gets calls (works fine)
app is closed: user click on nothification, home activity gets created because its the first run! (does not work)
thanks for any help!

Incorrect PendingIntent being launched after home key press

I have two (or more) widgets, e.g. A and B, which should launch the same activity passing their appWidgetId in the Intent extras to the activity. This works fine after application install on the first launch from any of the widgets (the activity receives the correct appWidgetId). It also works fine if I press the back button after activity launch and launch the activity from a different widget. However, if I launch the activity from widget A, hit the home button and then launch the activity from widget B (or C or D...) it launches with A's appWidgetId. I'm baffled as to how to fix this. Here is how I am declaring my PendingIntent:
Intent intent = new Intent(context, WidgetActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setAction(this.getClass().getName() + System.currentTimeMillis());
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
If I understand correctly, I am successfully setting up unique PendingIntents for each widget. Any help most appreciated!
EDIT:
The accepted answer to this question suggests that:
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.
However, my code creates randomized actions to perform and so I think my PendingIntents differ by more than just extras
Looks like I need to brush up on my activity lifecycle events. The answer was the following code put into my Activity:
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
super.onNewIntent(intent);
}
The problem was that, on Home button press, the Activity was holding onto the original Intent which launched it. Then, when the other widget launched the Activity, the original intent was being reused. The above code simply replaces the original intent with the new one and carries on with the remaining lifecycle events.

Widget launching a second instance of application

I am having problems launching my application from my widget when it's clicked upon.
Here is a cut of some code
// Create an Intent to launch activity
Intent intent = new Intent(context, Entry_MainTabView.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
updateViews.setOnClickPendingIntent(R.id.Widget, pendingIntent);
Now take the scenario.
I launch my app, exit to the home page , then click on my widget.
It launches a second instance of the application, so when I hit "back" , the application goes away and reveals the other copy. I then hit back again and finally go back to the homescreen.
How can I make the Intent only create a new instance if none already exists in ram ?
Have you looked at singleInstance and singleTask launch modes of an activity? This extract from Pro Android 2 indicates that there is no documented way of ensuring that there is only one instance of the widget running.

Categories

Resources