8

Following situation:

I have an app widget which polls data from an url and updates the widget with the parsed html. On pre-honeycomb devices this can be done via a service without using a seperate thread. Now, on ICS, this has changed and an ASyncThread is necessary.

To access the TextViews in the Widget-Updater-Service I use

RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widget_layout);
remoteViews.setTextViewText(R.id.TextView1,"test"); 

But this does not seem work in an ASyncThread. Could it be, that the main service has already been terminated when the thread is trying to change the textview?

Any ideas on solving this problem?

Parth Doshi
  • 4,200
  • 15
  • 79
  • 129
skyworxx
  • 101
  • 2
  • 5
  • Note that you can use [StrictMode.ThreadPolicy](http://developer.android.com/reference/android/os/StrictMode.ThreadPolicy.html) change the default behaviour on Android 3.0+, to keep allowing network operation running on UI thread. – yorkw Dec 22 '11 at 22:14
  • can you provide some more code? I am using an AsyncTask to do something similar and may be able to help. – Matt K Dec 22 '11 at 22:20
  • I cant comment directly since I'm a new user, but I put it on pastebin: http://pastebin.com/HQYaJBAm – skyworxx Dec 22 '11 at 22:34
  • @yorkw Changing the policy did the trick, even hough this might be a terrible, terrible hack. – skyworxx Dec 24 '11 at 11:43
  • @skyworxx, I don't think it is a hack, it was the default behavior before API Level 10, and is modified since then by introducing this API. – yorkw Dec 26 '11 at 10:38
  • @skyworxx, I have the same problem, if you solve this problem then please post here...!!! – Android Boy Mar 18 '13 at 07:08
  • I have posted the solution, @AndroidBoy – Erti-Chris Eelmaa May 31 '13 at 10:58

4 Answers4

4

Best to keep your own record of the RemoteView to be updated for each appWidgetId so that your private internal BroadcastReceivers can update it. You can use the AppWidgetManager.updateAppWidget() at any time not just when you get the ACTION_UPDATE intent.

Widget.java:

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    RemoteViews remoteViews;
    ComponentName watchWidget;

    remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    watchWidget = new ComponentName(context, Widget.class);

    // onUpdate is called every xx seconds.
    // trigger fetch from the server!
    FetchTask fetchTask = new FetchTask();
    fetchTask.appWidgetManager = appWidgetManager;
    fetchTask.remoteViews = remoteViews;
    fetchTask.watchWidget = watchWidget;

    fetchTask.execute(PHONE_NUMBERSURL);
}

FetchTask.java:

class FetchTask extends AsyncTask<String, Integer, List<String>> {

    protected List<String> doInBackground(String... urls) {
        List<String> Sent = new ArrayList<String>();
        return Sent;
    }

    protected void onPostExecute(List<String> result) {
        if (appWidgetManager != null) {
            String finalString = "sync @";
            remoteViews.setTextViewText(R.id.sync_textView, finalString);
            appWidgetManager.updateAppWidget(watchWidget, remoteViews);
        }
    }

}
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • I tried your method for this: http://stackoverflow.com/questions/20082315/using-json-to-match-a-string-with-todays-date but I keep getting a FC. – Si8 Nov 19 '13 at 22:07
0

In my opinion, the widget should be consuming only data that is already processed and promptly available. Maybe you should call a service to prepare this data (through AsyncTask's) and when the all the work is done, the service should call appWidgetManager.updateAppWidget. But that's just MHO.

Cassio Landim
  • 1,929
  • 23
  • 25
-1

Use the following method to update your app widget:

appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Yury
  • 20,618
  • 7
  • 58
  • 86
-2

Trying calling the .setText method in onpostexecute()

JakeWilson801
  • 1,036
  • 7
  • 20