package com.prashant.adesara.volleyexample; import java.io.File; import java.util.ArrayList; import java.util.List; import android.annotation.TargetApi; import android.app.ActionBar; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.android.volley.AuthFailureError; import com.android.volley.ClientError; import com.android.volley.NetworkError; import com.android.volley.NoConnectionError; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.ServerError; import com.android.volley.TimeoutError; import com.android.volley.VolleyError; import com.android.volley.toolbox.DiskBasedCache; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.ImageLoader.ImageCache; import com.android.volley.toolbox.Volley; import com.prashant.adesara.volleysample.model.FlickrImage; import com.prashant.adesara.volleysample.model.FlickrResponse; import com.prashant.adesara.volleysample.model.FlickrResponsePhotos; import com.prashant.adesara.volleysample.toolbox.GsonRequest; import com.prashant.adesara.volleysample.util.BitmapUtil; public class GSONObjectRequestActivity extends Activity { private Button mTrigger; private RequestQueue mVolleyQueue; private ListView mListView; private EfficientAdapter mAdapter; private ProgressDialog mProgress; private List<DataModel> mDataList; private ImageLoader mImageLoader; private final String TAG_REQUEST = "MY_TAG"; private class DataModel { private String mImageUrl; private String mTitle; public String getImageUrl() { return mImageUrl; } public void setImageUrl(String mImageUrl) { this.mImageUrl = mImageUrl; } public String getTitle() { return mTitle; } public void setTitle(String mTitle) { this.mTitle = mTitle; } } /* * Extends from DisckBasedCache --> Utility from volley toolbox. * Also implements ImageCache, so that we can pass this custom implementation * to ImageLoader. */ public class DiskBitmapCache extends DiskBasedCache implements ImageCache { public DiskBitmapCache(File rootDirectory, int maxCacheSizeInBytes) { super(rootDirectory, maxCacheSizeInBytes); } public DiskBitmapCache(File cacheDir) { super(cacheDir); } public Bitmap getBitmap(String url) { final Entry requestedItem = get(url); if (requestedItem == null) return null; return BitmapFactory.decodeByteArray(requestedItem.data, 0, requestedItem.data.length); } public void putBitmap(String url, Bitmap bitmap) { final Entry entry = new Entry(); entry.data = BitmapUtil.convertBitmapToBytes(bitmap) ; put(url, entry); } } GsonRequest<FlickrResponsePhotos> gsonObjRequest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.json_object_layout); actionBarSetup(); // Initialise Volley Request Queue. mVolleyQueue = Volley.newRequestQueue(this); int max_cache_size = 1000000; mImageLoader = new ImageLoader(mVolleyQueue, new DiskBitmapCache(getCacheDir(),max_cache_size)); mDataList = new ArrayList<DataModel>(); mListView = (ListView) findViewById(R.id.image_list); mTrigger = (Button) findViewById(R.id.send_http); mAdapter = new EfficientAdapter(this); mListView.setAdapter(mAdapter); mTrigger.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showProgress(); makeSampleHttpRequest(); } }); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void actionBarSetup() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ActionBar ab = getActionBar(); ab.setTitle("GSONResponseParsing"); } } public void onStop() { super.onStop(); if(mProgress != null) mProgress.dismiss(); } private void makeSampleHttpRequest() { String url = "http://api.flickr.com/services/rest"; Uri.Builder builder = Uri.parse(url).buildUpon(); builder.appendQueryParameter("api_key", "5e045abd4baba4bbcd866e1864ca9d7b"); builder.appendQueryParameter("method", "flickr.interestingness.getList"); builder.appendQueryParameter("format", "json"); builder.appendQueryParameter("nojsoncallback", "1"); gsonObjRequest = new GsonRequest<FlickrResponsePhotos>(Request.Method.GET, builder.toString(), FlickrResponsePhotos.class, null, new Response.Listener<FlickrResponsePhotos>() { @Override public void onResponse(FlickrResponsePhotos response) { try { parseFlickrImageResponse(response); mAdapter.notifyDataSetChanged(); } catch (Exception e) { e.printStackTrace(); showToast("JSON parse error"); } stopProgress(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // Handle your error types accordingly.For Timeout & No connection error, you can show 'retry' button. // For AuthFailure, you can re login with user credentials. // For ClientError, 400 & 401, Errors happening on client side when sending api request. // In this case you can check how client is forming the api and debug accordingly. // For ServerError 5xx, you can do retry or handle accordingly. if( error instanceof NetworkError) { } else if( error instanceof ClientError) { } else if( error instanceof ServerError) { } else if( error instanceof AuthFailureError) { } else if( error instanceof ParseError) { } else if( error instanceof NoConnectionError) { } else if( error instanceof TimeoutError) { } stopProgress(); showToast(error.getMessage()); } }); gsonObjRequest.setTag(TAG_REQUEST); mVolleyQueue.add(gsonObjRequest); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } private void showProgress() { mProgress = ProgressDialog.show(this, "", "Loading..."); } private void stopProgress() { mProgress.cancel(); } private void showToast(String msg) { Toast.makeText(GSONObjectRequestActivity.this, msg, Toast.LENGTH_LONG).show(); } private void parseFlickrImageResponse(FlickrResponsePhotos response) { mDataList.clear(); FlickrResponse photos = response.getPhotos(); for(int index = 0 ; index < photos.getPhotos().size(); index++) { FlickrImage flkrImage = photos.getPhotos().get(index); String imageUrl = "http://farm" + flkrImage.getFarm() + ".static.flickr.com/" + flkrImage.getServer() + "/" + flkrImage.getId() + "_" + flkrImage.getSecret() + "_t.jpg"; DataModel model = new DataModel(); model.setImageUrl(imageUrl); model.setTitle(flkrImage.getTitle()); mDataList.add(model); } } private class EfficientAdapter extends BaseAdapter { private LayoutInflater mInflater; public EfficientAdapter(Context context) { mInflater = LayoutInflater.from(context); } public int getCount() { return mDataList.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.image = (ImageView) convertView.findViewById(R.id.image); holder.title = (TextView) convertView.findViewById(R.id.title); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.title.setText(mDataList.get(position).getTitle()); mImageLoader.get(mDataList.get(position).getImageUrl(), ImageLoader.getImageListener(holder.image,R.drawable.flickr, android.R.drawable.ic_dialog_alert), //Specify width & height of the bitmap to be scaled down when the image is downloaded. 50,50); return convertView; } class ViewHolder { TextView title; ImageView image; } } }