2 buttons on widget - refresh and show activity

104 Views Asked by At

I have widget with 2 buttons button with id refresh and second button with id detailsInfo. First button should trigger widget update, second button to show detailed info (downloaded after widget refreshed). This is weather widget. Refresh should trigger to download full weather data. Basic weather info should be displayed directly on widget, full data on details activity, launched on detailsInfo button click.

This is my code:

public class AppWidget extends AppWidgetProvider
{

    public static String ACTION_DETAILS = "m.m.meteowidget.ACTION_DETAILS";

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Log.i("onReceive",intent.getAction());

        super.onReceive(context, intent);
    }

    @Override
    public void onUpdate(Context ctxt, AppWidgetManager mgr, int[] appWidgetIds)
    {
        ComponentName me = new ComponentName(ctxt, AppWidget.class);
        final RemoteViews updateViews = new RemoteViews(ctxt.getPackageName(), R.layout.widget_layout);

        Intent intent = new Intent(ctxt, AppWidget.class);
        intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

        PendingIntent pi = PendingIntent.getBroadcast(ctxt, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        updateViews.setOnClickPendingIntent(R.id.refresh, pi);


        Intent intent2 = new Intent(ctxt, DetailsActivity.class);
        intent2.setAction(ACTION_DETAILS);
        PendingIntent di = PendingIntent.getActivity(ctxt, 0, intent2, 0);
        updateViews.setOnClickPendingIntent(R.id.detailsInfo, di);


        mgr.updateAppWidget(me, updateViews);


        for (int i = 0; i < appWidgetIds.length; i++)
            new WeatherInfo(updateViews,appWidgetIds[i],mgr).execute();

    }
}

WeatherInfo is class that actually performs weather details download (it extends AsyncTask). As you can see, it gets my updateViews as constructor argument and then sets basic weather info displayed on my widget.

However, I have no idea how to display detailed info activity and pass detailed weather info to it. When I try to run my activity as shown above, my widget fails to load ("Problems loading widget"), without any exception that I can debug.

Any ideas what am I doing wrong?

[edit] This seems to be (almost) ok:

Widget provider:

 @Override
    public void onReceive(Context context, Intent intent)
    {
        Log.i("onReceive",intent.getAction());

        super.onReceive(context, intent);
    }

    @Override
    public void onUpdate(Context ctxt, AppWidgetManager mgr, int[] appWidgetIds)
    {
        ComponentName me = new ComponentName(ctxt, AppWidget.class);
        final RemoteViews updateViews = new RemoteViews(ctxt.getPackageName(), R.layout.widget_layout);

        Intent intent = new Intent(ctxt, AppWidget.class);
        intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

        PendingIntent pi = PendingIntent.getBroadcast(ctxt, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        updateViews.setOnClickPendingIntent(R.id.refresh, pi);


        mgr.updateAppWidget(me, updateViews);


        Intent intent2 = new Intent(ctxt, DetailsActivity.class);
        intent2.setAction(ACTION_DETAILS);
        PendingIntent di = PendingIntent.getActivity(ctxt, 0, intent2, 0);
        updateViews.setOnClickPendingIntent(R.id.detailsInfo, di);
        mgr.updateAppWidget(me, updateViews);


        for (int i = 0; i < appWidgetIds.length; i++)
            new WeatherInfo(updateViews,appWidgetIds[i],mgr).execute();

    }

My async task:

public class WeatherInfo extends AsyncTask<String, Void, Map>
{
    private RemoteViews views;
    private int WidgetID;
    private AppWidgetManager WidgetManager;
    private DetailsActivity detailsActivity;

    public WeatherInfo(RemoteViews views, int appWidgetID, AppWidgetManager appWidgetManager)
    {
        this.views = views;
        this.WidgetID = appWidgetID;
        this.WidgetManager = appWidgetManager;
    }



    @Override
    protected Map doInBackground(String... strings)
    {
        Document doc = null;
        try
        {
            doc = Jsoup.connect("http://meteo.uwb.edu.pl/").get();
        }
        catch (IOException e)
        {
            Log.e("","Connection failed: " + e.getMessage());
            return null;
        }
        Elements tables = doc.select("td");
        Elements headers = tables.get(2).select("b");
        Elements vals = tables.get(3).select("b");
        Map all = new LinkedHashMap();

        for (int i=0;i<headers.size() ; i++)
            all.put(headers.get(i).text(),vals.get(i).text());

        Global.weatherInfo = all;

        return all;
    }

    @Override
    protected void onPostExecute(Map map)
    {
        if(map==null) return;


        String txt = "";


        String temp = (String) map.values().toArray()[0];
        String hum =  (String) map.values().toArray()[1];
        String pressure =  (String) map.values().toArray()[2];
        String temp2 =  "Odczuwalna: " + map.values().toArray()[3];




        views.setTextViewText(R.id.info_temp, temp);
        views.setTextViewText(R.id.info_temp2, temp2);
        views.setTextViewText(R.id.info_hum, hum);
        views.setTextViewText(R.id.info_pressure, pressure);




        WidgetManager.updateAppWidget(WidgetID, views);
    }

}

So I there is Global class with weatherInfo static field to share value between my thread and details activity.

However, there are 2 things that I have no idea how to fix: - if activity is destroyed (removed from last app list in Android), after I press details button on my widget, activity is empty (bacause Global.weather info is null). I need to trigger widget refresh again and then lanunch my activity - if I try to set Global.weatherInfo inside PostExecute method my widgets fails to show, without any exception thrown - why? - I also tried to trigger my async task on create my activity. So i created second WeatherInfo constructor and passed DetailSActivity object into this, to be able to refresh my activity. Even if I don't use that second constructor, my widgets again fails to load without any exception.

I'm confused, can anybody tell me what's going on here? And how to solve my problem?

2

There are 2 best solutions below

1
On

Create AsyncTask separately. Return the values from postexecute() method. Handler will give you better solution to handle response of asynktask. Call this asynctask before populating the values in UI components. Handle error case separately either by dialogue box whatever you wish. follow the link for clearance in handler

0
On

I made it working by storing data in sqlite database. So, after widget refresh, all data are saved to database. Database is also for data cache, so if there is no internet connection, widget disaplays cached data. The same cached data will be loaded to be displayed on my activity.