The code here in onHandleIntent:
RemoteViews views = new RemoteViews(getPackageName(), R.layout.mylayout);
views.setTextViewText(R.id.txtView1, "some string");
...
Bundle bundle = intent.getExtras();
int id = bundle.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(id, views);
does not update the widget's TextView named txtView1. I've searched and searched, but it appears that everything I've done seems to match what I found.
You need Handler to update UI from worker thread.
You can take help from this tutorial
http://crodrigues.com/updating-the-ui-from-a-background-thread-on-android/
or alternatively you can use Asynctask if you don't want to get into thread and handler stuff.
Asynctask manages this stuff by itself and you can update UI in onPostExecute() method and so on..
You can read details about asynctask in developer android site of google.
You have to update your textview in app widget development.
RemoteViews views = new RemoteViews(getPackageName(), R.layout.mylayout);
views.setTextViewText(R.id.txtView1, "some string");
thisWidget = new ComponentName(context, WatchWidget.class);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
Sigh, thank you all for your answers, unfortunately it was my mistake. In my onUpdate from my custom AppWidgetProvider, I was passing the wrong Id. I've switched it now to the proper Id, and each widget instance updates properly.
Related
I have a widget whose content is very similar to what is seen in the actual app, i.e. images and text just on a smaller scale.
I am using the following code to make the widget update after the activity UI updates - only it is not working and the widget it not updating:
Intent i = new Intent(mContext, ExtensionOfAppWidgetProvider.class);
i.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
mContext.sendBroadcast(i);
I cannot get the onUpdate() of the AppWidgetProvider class to be called without removing the widget and then placing it back on the homescreen.
Any help is appreciated.
Thanks.
Here was the culprit...a couple lines of code were missing from the onReceive() of my AppWidgetProvider class.
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
int[] ids = mgr.getAppWidgetIds(new ComponentName(context, PromoStackWidgetProvider.class));
for(int id : ids) {
mgr.notifyAppWidgetViewDataChanged(id, R.id.stack_view);
}
Make sure that your widget has itself as a registered broadcast reciever in your AndroidManifest.xml
I'm trying to update a widget from a service... the service start a thread that execute this code
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(Worker.this);
RemoteViews remoteViews = new RemoteViews(Worker.this.getPackageName(), R.layout.mywidget);
ComponentName projectWidget = new ComponentName(Worker.this, MyWidget.class);
remoteViews.setTextViewText(R.id.widgetstate, "update");
appWidgetManager.updateAppWidget(projectWidget, remoteViews);
the onUpdate method just print a log, but this log is printed only when I create the widget, not everytime the thread cycles... where I'm wrong?
Thanks in advance
You're not wrong. You just update the widget without calling onUpdate(). It's just a convinience method that gets called in response to the ACTION_APPWIDGET_UPDATE broadcast by the system. You don't have to call it to update a widget, it also just works like you did here. ¹
To invoke it you can send the broadcast or call it by hand though, it's a good idea to keep the widget update functionality in one place from a code structure point of view to find things easily.
¹ Take a look at the AppWidgetProvider source, line 56. The whole AppWidgetProvider is just a BroadcastReceiver that does some work for you already - and it does start the update in the same way.
Probably a stupid question, but where and how do I access my widget controls?
With normal programs I call setContentView(R.layout.blah) and then use findViewById(R.id.blah)
to access the controls, but how do I do the same for widgets? Do I need to call setContentView() somewhere or..? The widget looks just fine without calling it anywhere.
As it comes out there's now way to access them directly. Instead you have to do this:
RemoteViews remoteViews =
new RemoteViews(ctx.getPackageName(), R.layout.folder_view_mywidget);
ComponentName thisWidget = new ComponentName(ctx, FolderViewProvider.class);
Then you use methods from Remoteviews to set all the fields you want like this:
remoteViews.setTextViewText(R.id.text1_1, "text");
And then finally you call this to execute the changes:
AppWidgetManager.getInstance(ctx).updateAppWidget(thisWidget, remoteViews);
I am trying to open my activity when a user clicks on a button in my HomeScreen Widget. But I guess the app is not responding to my onclick. Here is my code snippet :
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.layout_appwidget);
Intent launchActivity = new Intent();
launchActivity.setClass(context,UpdatesScreen.class);
launchActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context,0, launchActivity, 0);
remoteViews.setOnClickPendingIntent(R.id.iv_widget, pendingIntent);
ComponentName thisWidget = new ComponentName(context, MyAppWidgetProvider.class.getName());
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(thisWidget, remoteViews);
I have copied the same code in onUpdate as well as onEnabled method of MyAppWidgetProvider class. But still it's not working at all.
I have read many post regarding this issue but all are using the same code. Am I doing something wrong?? What is the right way to do the same.
Thanks in advance.
I have found the mistake. Posting my answer to help someone facing the same issue.
Actually, I was overriding both the method onUpdate() as well as onReceive(). If we override onReceive(), in that case onUpdate() never gets called. and I wasn't using ACTION_APPWIDGET_UPDATE as an action in onReceive() too.
In my onUpdate method in my AppWidgetProvider class, I ended up executing a non-trivial amount of code so that I can completely recreate a new RemoteView object. The reality is I really only need to be setting the text in one of the TextViews in the RemoteViews each time I update.
Is there any way to just modify the RemoteViews that a particular widget is already using?
First, RemoteView is not a View. It's a set of instructions that build a View hierarchy. It is used to recreate a View in another process (App Widgets do not execute in your app's process). As such it's serializable and mutable.
So, when you initialize a RemoteView just store a reference to it somewhere, e.g. in a field of your custom AppWidgetProvider.
Next time you need it, get it from field and the change something on it. For changing the string in a TextView use setString(..).
remoteView.setString(textViewId, "setText", "some text for TextView")
This is the 2013 update if you are using current API's. In your WidgetProvider class' method that will perform an update:
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
rv = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
rv.setTextViewText(R.id.ofTextViewInWidgetLayoutXML, "Hello World");
appWidgetManager.partiallyUpdateAppWidget(appWidgetIds[i], rv);
Note that it is no longer remoteView.setString but remoteView.setTextViewText
You can update the remote views and then call
ComponentName componentName= new ComponentName(context, YourClass.class);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
on, which AFAIK should update the widget