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.
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.