Launching an activity from an AppWidget - android

How do i launch an activity from an AppWidget? I want to give the user the ability to edit its settings.

All the AppWidget methods have a Context: you can use that to create an Intent to launch your Activity.
EDIT: strictly speaking, you don't even need the Context (just create an Intent and then call startActivity).

you can find a lot of examples around the internet this example is excellent courtesy of Mark Murphy
https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget

You have to do something like this:
Intent intent = new Intent(context, MainWidgetActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.appwidget);
rv.setOnClickPendingIntent(R.id.button, pendingIntent);
while MainWidgetActivity.class is the Activity you want to launch

Related

Configure Widgets with difference content

My app creates many widgets of the same type, but with different content. When the user clicks on one widget, it is important to know the widgetId, so I know the content to update.
My way seems to be totaly wrong, because my PendingIntent gets overridden. So I always get the same EXTRA_APPWIDGET_ID instead of n different ones.
Here is my code, the part when I set the PendingIntent for my OnClick.
// edit intent
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.base_info_widget);
Intent editIntent = new Intent(context,MainActivity.class);
editIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.putExtra(GlobalVariables.COMMAND_KEY_ACTION,GlobalVariables.COMMAND_VALUE_EDIT);
editIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
Log.d(MY_TAG, "putExtra EXTRA_APPWIDGET_ID="+ Integer.toString(appWidgetId));
PendingIntent pendingEditIntent = PendingIntent.getActivity(context, 0, editIntent, PendingIntent.FLAG_CANCEL_CURRENT);
views.setOnClickPendingIntent(R.id.layout_wrapper, pendingEditIntent);
I hope my question was clear. How can I solve that problem?
Make your intent unique:
editIntent.setData(Uri.parse(editIntent.toUri(Intent.URI_INTENT_SCHEME)));
That's why you get always same id on all widgets

How to start a service from App Widget in Android

I am making a home screen App Widget for my Android app. In that App Widget there is a ListView. That ListView has a custom layout which has a TextView & an ImageButton. I am setting a PendingIntent on that ImageButton to start the service as follows:
Intent intent = new Intent(mContext, MyService.class);
intent.putExtra(MyConstants.MY_EXTRA, c.getString(c.getColumnIndex(MyColumns.MY_COLUMN_TITLE)));
intent.setAction(MyConstants.MY_ACTION);
PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.MyImageButton, pendingIntent);
in getViewAt method of RemoteViewsFactory. But on clicking the ImageButton the service does not start.
I have put an intentfilter with MY_ACTION for MyService. And also tried without it which did not make things work.
Anyone knows how to start service on click of a button inside a list view item in home screen App Widget in Android?
Everything works fine i.e. the ListView is populated perfectly from SQLite database.
From the android javadoc
public void setOnClickPendingIntent
Equivalent to calling
setOnClickListener(android.view.View.OnClickListener) to launch the
provided PendingIntent. When setting the on-click action of items
within collections (eg. ListView, StackView etc.), this method will
not work. Instead, use {#link
RemoteViews#setPendingIntentTemplate(int, PendingIntent) in
conjunction with RemoteViews#setOnClickFillInIntent(int, Intent).
In your update method of your AppWidgetProvider you have to add
final PendingIntent clickPendingIntentTemplate = PendingIntent.getService...
views.setPendingIntentTemplate(R.id.widget_list, clickPendingIntentTemplate);
and in the getViewAt method of your RemoteViewsFactory :
final Intent fillInIntent = new Intent();
fillInIntent.putExtra(...);
views.setOnClickFillInIntent(R.id.widget_list_item, fillInIntent);

Passing extras from widget in PendingIntent to Activity

I can't find a way to pass extras from widget to Activity properly.
I wan't to open activity on button click with some extras passed.
Intent intent = new Intent(context, CreateOperationsActivity.class);
intent.putExtra("someKey", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, Constants.RequestCodes.CREATE_OPERATIONS, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.add_expense_button, pendingIntent);
Activity is opened, but there is no extra in the Intent.
The only way I was able to pass that extra was seting PendingIntent flag to PendingIntent.FLAG_ONE_SHOT but then widget button works only wonce, clicking it further takes no action.
How to do that so the extra is intercepted by Activity and the button works each time?
You're probably missing setAction() for your Intent ;) See this one for a better explanation: https://stackoverflow.com/a/3128271/515423

Using the ShareCompat library from an App Widget

I would like to create a pending intent for my app widget view that will launch a sharing intent. The problem is that there is no reference to any activity in the android.appwidget.AppWidgetProvider class. The code below does not work because I don't have access to the MainMenuActivity class. Any ideas, is this even possible?
Intent shareIntent = ShareCompat.IntentBuilder.from(MainMenuActivity.this)
.setText("Some text")
.setType("text/plain")
.getIntent();
PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, shareIntent, 0);
views.setOnClickPendingIntent(R.id.widget_layout, actionPendingIntent);
Pass in the Context supplied as a parameter to your onUpdate() method to the from() method on ShareCompat.IntentBuilder.
UPDATE
Sorry, it looks like ShareCompat.IntentBuilder will only work with Activity, not a generic Context like most other things in Android. Hence, you will not be able to use it from an app widget.

How do I cancel Pending Intents in a Android Widget?

I've got some weird behavior and I can only assume is because of the Pending intents I am using.
Scenario
I have a widget (4x1) which has 4 buttons. Within onUpdate of the widget, I add an pending intent for each button. My intents fires a Service with a bundeled parameter and depending on this parameter starts something. I attach intents as this:
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Bundle b = new Bundle();
b.putString("myVariable", someVariable);
Intent intent = new Intent(context, AppStarterService.class);
intent.putExtras(b);
PendingIntent pendingIntent = PendingIntent.getService(context, buttopnPosition, intent, 0);
views.setOnClickPendingIntent(R.id.btnOne, pendingIntent);
The problem
The code works just fine, until the user decides to update the content of the button. Then, a new Pending Intent is done. So, when I press again the button, sometimes it still executes the old intent and not the new one. I don't know how to explain this better. Let's say for my first intent the parameter is "TestOne", after my update, the new intent has parameter "TestX". When the user clicks on the button, on my service I get in intent extras still "TestOne" instead "TestX". So, my guess is that somehow, I need to cancel the previous intent, when the widget button content changes.
Is this the issue ? Am I doing something wrong ? How do I cancel the old intent, I need to recreate it and then cancel it ?
Thank you for your time.
I you keep having this problem even with FLAG_UPDATE_CURRENT, try defining a different requestCode each time, with something like this:
private static int request = 0;
...
PendingIntent pendingIntent = PendingIntent.getService(context, request++, intent, 0);
So each time a new PendingIntent is created, a new requestCode is used, at least during class life.
I hope it helps.
I think you want to set the flag http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_UPDATE_CURRENT as the last parameter to PendingIntent.getService

Categories

Resources