Search code examples
androidandroid-appwidgetappwidgetprovider

How To Create AppWidget to display JSON Parse Images and Text


I'm New to android development and I don't understand clearly how to create a appwidget for application that parse JSON Data and display in list.


Solution

  • I solved my problem using this link (https://laaptu.wordpress.com/2013/07/19/android-app-widget-with-listview/).

    It has Series of Tutorials (1.app widget with listview 2.populate app widget listview with data from web 3.download images and show on imageview of appwidget with listview 4.setting update interval on appwidget with listview 5.how to make appwidget update work after phone reboot)

    To Use Simple JSON URL to fetch images and texts, i made the following changes in RemoteFetchService.java from third tutorial,

    import java.util.ArrayList;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import android.app.Service;
    import android.appwidget.AppWidgetManager;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.os.AsyncTask;
    import android.os.IBinder;
    import android.util.Log;
    
    import com.androidquery.AQuery;
    import com.androidquery.callback.AjaxCallback;
    import com.androidquery.callback.AjaxStatus;
    import com.example.mk.widgets.data.DatabaseManager;
    import com.example.mk.widgets.data.FileManager;
    
    public class RemoteFetchService extends Service {
    
    private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    
    JSONObject jsonobject;
    JSONArray jsonarray;
    AQuery aquery;
    private String remoteJsonUrl =   "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors";
    
    public static ArrayList<ListItem> listItemList;
    private int count = 0;
    
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    
    /*
     * Retrieve appwidget id from intent it is needed to update widget later
     * initialize our AQuery class
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID))
            appWidgetId = intent.getIntExtra(
                    AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
        aquery = new AQuery(getBaseContext());
        new DownloadJSON().execute();
        return super.onStartCommand(intent, flags, startId);
    }
    
    // DownloadJSON AsyncTask
    private class DownloadJSON extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            // Create an array
            listItemList = new ArrayList<ListItem>();
            // Retrieve JSON Objects from the given URL address
            jsonobject = JSONfunctions.getJSONfromURL(remoteJsonUrl);
            try {
                // Locate the array name in JSON
                jsonarray = jsonobject.getJSONArray("actors");
    
                for (int i = 0; i < jsonarray.length(); i++) {
                    jsonobject = jsonarray.getJSONObject(i);
                    // Retrive JSON Objects
                    ListItem listItem = new ListItem();
                    listItem.heading = jsonobject.getString("name");
                    listItem.content = jsonobject.getString("country");
                    listItem.imageUrl = jsonobject.getString("image");
                    listItemList.add(listItem);
                }
                storeListItem();
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }
    }
    /**
     * Instead of using static ArrayList as we have used before,no we rely upon
     * data stored on database so saving the fetched json file content into
     * database and at same time downloading the image from web as well
     */
    private void storeListItem() {
        DatabaseManager dbManager = DatabaseManager.INSTANCE;
        dbManager.init(getBaseContext());
        dbManager.storeListItems(appWidgetId, listItemList);
    
        int length = listItemList.size();
        for (int i = 0; i < length; i++) {
            ListItem listItem = listItemList.get(i);
            final int index = i;
            aquery.ajax(listItem.imageUrl, Bitmap.class,new AjaxCallback<Bitmap>() {
                        @Override
                        public void callback(String url, Bitmap bitmap, AjaxStatus status) {
                            super.callback(url, bitmap, status);
                            storeBitmap(index, bitmap);
                        };
                    });
        }
    }
    /**
     * Saving the downloaded images into file and after all the download of
     * images be complete begin to populate widget as done previously
     */
    private void storeBitmap(int index, Bitmap bitmap) {
        FileManager.INSTANCE.storeBitmap(appWidgetId, bitmap,
                listItemList.get(index).heading, getBaseContext());
        count++;
        Log.i("count",String.valueOf(count) + "::"+ Integer.toString(listItemList.size()));
        if (count == listItemList.size()) {
            count = 0;
            populateWidget();
        }
    
    }
    
    /**
     * Method which sends broadcast to WidgetProvider so that widget is notified
     * to do necessary action and here action == WidgetProvider.DATA_FETCHED
     */
    private void populateWidget() {
    
        Intent widgetUpdateIntent = new Intent();
        widgetUpdateIntent.setAction(WidgetProvider.DATA_FETCHED);
        widgetUpdateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                appWidgetId);
        sendBroadcast(widgetUpdateIntent);
    
        this.stopSelf();
    }
    }
    

    JSONfunctions.java

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import android.util.Log;
    
    public class JSONfunctions {
    
    public static JSONObject getJSONfromURL(String url) {
        InputStream is = null;
        String result = "";
        JSONObject jArray = null;
    
        // Download JSON data from URL
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
    
        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }
    
        // Convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }
    
        try {
    
            jArray = new JSONObject(result);
        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
    
        return jArray;
    }
    }
    

    Hope this helps someone and Great thanks to ( https://stackoverflow.com/users/739306/laaptu ) for the tutorials.