├── .gitignore ├── CaptechBuzz ├── .settings │ └── org.eclipse.jdt.core.prefs ├── AndroidManifest.xml ├── ic_launcher-web.png ├── libs │ ├── android-support-v4.jar │ ├── disklrucache-2.0.1.jar │ ├── gson-2.2.4.jar │ └── volley.jar ├── lint.xml ├── proguard-project.txt ├── project.properties ├── res │ ├── drawable-hdpi │ │ ├── ic_launcher_captech.png │ │ └── logo_captech.png │ ├── drawable-ldpi │ │ └── logo_captech.png │ ├── drawable-mdpi │ │ ├── ic_launcher_captech.png │ │ └── logo_captech.png │ ├── drawable-xhdpi │ │ ├── ic_launcher_captech.png │ │ └── logo_captech.png │ ├── drawable-xxhdpi │ │ └── ic_launcher_captech.png │ ├── layout │ │ ├── activity_main.xml │ │ └── tweet_list_item.xml │ ├── values-sw600dp │ │ └── dimens.xml │ ├── values-sw720dp-land │ │ └── dimens.xml │ ├── values-v11 │ │ └── styles.xml │ ├── values-v14 │ │ └── styles.xml │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml ├── src │ └── com │ │ └── captechconsulting │ │ └── captechbuzz │ │ ├── BuzzArrayAdapter.java │ │ ├── MainActivity.java │ │ ├── MainApplication.java │ │ └── model │ │ ├── GsonRequest.java │ │ ├── RequestManager.java │ │ ├── images │ │ ├── BitmapLruImageCache.java │ │ ├── DiskLruImageCache.java │ │ └── ImageCacheManager.java │ │ └── twitter │ │ ├── Tweet.java │ │ ├── TweetData.java │ │ └── TwitterManager.java └── tmp │ └── cached-robolectric-classes.jar ├── LICENSE-2.0.txt ├── README.md └── Screenshots └── framed_buzzscreenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project -------------------------------------------------------------------------------- /CaptechBuzz/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.6 12 | -------------------------------------------------------------------------------- /CaptechBuzz/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /CaptechBuzz/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/ic_launcher-web.png -------------------------------------------------------------------------------- /CaptechBuzz/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/libs/android-support-v4.jar -------------------------------------------------------------------------------- /CaptechBuzz/libs/disklrucache-2.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/libs/disklrucache-2.0.1.jar -------------------------------------------------------------------------------- /CaptechBuzz/libs/gson-2.2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/libs/gson-2.2.4.jar -------------------------------------------------------------------------------- /CaptechBuzz/libs/volley.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/libs/volley.jar -------------------------------------------------------------------------------- /CaptechBuzz/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /CaptechBuzz/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /CaptechBuzz/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-hdpi/ic_launcher_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-hdpi/ic_launcher_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-hdpi/logo_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-hdpi/logo_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-ldpi/logo_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-ldpi/logo_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-mdpi/ic_launcher_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-mdpi/ic_launcher_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-mdpi/logo_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-mdpi/logo_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-xhdpi/ic_launcher_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-xhdpi/ic_launcher_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-xhdpi/logo_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-xhdpi/logo_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/drawable-xxhdpi/ic_launcher_captech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/res/drawable-xxhdpi/ic_launcher_captech.png -------------------------------------------------------------------------------- /CaptechBuzz/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /CaptechBuzz/res/layout/tweet_list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 26 | 27 | 37 | 38 | 49 | 50 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #0000FF 4 | #000000 5 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Buzz 5 | Settings 6 | 7 | -------------------------------------------------------------------------------- /CaptechBuzz/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/BuzzArrayAdapter.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | import java.util.List; 6 | import java.util.Locale; 7 | 8 | import android.content.Context; 9 | import android.util.Log; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.ArrayAdapter; 14 | import android.widget.TextView; 15 | 16 | import com.android.volley.Response.ErrorListener; 17 | import com.android.volley.Response.Listener; 18 | import com.android.volley.VolleyError; 19 | import com.android.volley.toolbox.NetworkImageView; 20 | import com.captechconsulting.captechbuzz.model.images.ImageCacheManager; 21 | import com.captechconsulting.captechbuzz.model.twitter.Tweet; 22 | import com.captechconsulting.captechbuzz.model.twitter.TweetData; 23 | import com.captechconsulting.captechbuzz.model.twitter.TwitterManager; 24 | 25 | /** 26 | * 27 | * @author Trey Robinson 28 | * 29 | */ 30 | public class BuzzArrayAdapter extends ArrayAdapter implements Listener, ErrorListener { 31 | 32 | private final String TAG = getClass().getSimpleName(); 33 | 34 | private static final SimpleDateFormat sdf = new SimpleDateFormat("M/d/yy h:mm a", Locale.US); 35 | 36 | /** 37 | * The data that drives the adapter 38 | */ 39 | private final List mData; 40 | 41 | /** 42 | * The last network response containing twitter metadata 43 | */ 44 | private TweetData mTweetData; 45 | 46 | private boolean isLoading; 47 | 48 | 49 | /** 50 | * Flag telling us our last network call returned 0 results and we do not need to execute any new requests 51 | */ 52 | private boolean moreDataToLoad; 53 | 54 | /** 55 | * @param context 56 | * The context 57 | * @param textViewResourceId 58 | * Resource for the rows of the listview 59 | * @param newData 60 | * Initial dataset. 61 | */ 62 | public BuzzArrayAdapter(Context context, TweetData newData) { 63 | super(context, R.layout.tweet_list_item); 64 | mData = newData.getTweets(); 65 | mTweetData = newData; 66 | 67 | moreDataToLoad = true; 68 | } 69 | 70 | @Override 71 | public View getView(int position, View convertView, ViewGroup parent) { 72 | 73 | View v = convertView; 74 | ViewHolder viewHolder; 75 | 76 | //check to see if we need to load more data 77 | if(shouldLoadMoreData(mData, position) ) { 78 | loadMoreData(); 79 | } 80 | 81 | if(v == null){ 82 | LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 83 | v = inflater.inflate(R.layout.tweet_list_item, null); 84 | 85 | viewHolder = new ViewHolder(); 86 | viewHolder.twitterUserImage = (NetworkImageView)v.findViewById(R.id.twitterUserImage); 87 | viewHolder.userNameTextView = (TextView)v.findViewById(R.id.usernameTextView); 88 | viewHolder.messageTextView = (TextView)v.findViewById(R.id.messageTextView); 89 | viewHolder.tweetTimeTextView = (TextView)v.findViewById(R.id.tweetTimeTextView); 90 | 91 | v.setTag(viewHolder); 92 | 93 | } else { 94 | viewHolder = (ViewHolder) v.getTag(); 95 | } 96 | 97 | Tweet tweet = mData.get(position); 98 | if(tweet != null){ 99 | viewHolder.twitterUserImage.setImageUrl(tweet.getUserImageUrl(), ImageCacheManager.getInstance().getImageLoader()); 100 | viewHolder.userNameTextView.setText("@" + tweet.getUsername()); 101 | viewHolder.messageTextView.setText(tweet.getMessage()); 102 | viewHolder.tweetTimeTextView.setText(formatDisplayDate(tweet.getCreatedDate())); 103 | viewHolder.destinationUrl = tweet.getDestinationUrl(); 104 | } 105 | 106 | return v; 107 | } 108 | 109 | @Override 110 | public int getCount() { 111 | return mData.size(); 112 | } 113 | 114 | private String formatDisplayDate(Date date){ 115 | if(date != null){ 116 | return sdf.format(date); 117 | } 118 | 119 | return ""; 120 | } 121 | /** 122 | * Add the data to the current listview 123 | * @param newData 124 | * Data to be added to the listview 125 | */ 126 | public void add(List newData) 127 | { 128 | isLoading = false; 129 | if(!newData.isEmpty()){ 130 | mData.addAll(newData); 131 | notifyDataSetChanged(); 132 | } 133 | } 134 | 135 | /** 136 | * a new request. 137 | * @param data 138 | * Current list of data 139 | * @param position 140 | * Current view position 141 | * @return 142 | */ 143 | private boolean shouldLoadMoreData(List data, int position){ 144 | // If showing the last set of data, request for the next set of data 145 | boolean scrollRangeReached = (position > (data.size() - TwitterManager.TWITTER_DEFAULT_PAGE_SIZE)); 146 | return (scrollRangeReached && !isLoading && moreDataToLoad); 147 | } 148 | 149 | private void loadMoreData(){ 150 | isLoading = true; 151 | Log.v(getClass().toString(), "Load more tweets"); 152 | TwitterManager.getInstance().getDefaultHashtagTweets(this, this, null, mTweetData.getPage() + 1); 153 | } 154 | 155 | 156 | /** 157 | * Viewholder for the listview row 158 | * 159 | * @author Trey Robinson 160 | * 161 | */ 162 | static class ViewHolder{ 163 | NetworkImageView twitterUserImage; 164 | TextView userNameTextView; 165 | TextView messageTextView; 166 | TextView tweetTimeTextView; 167 | String destinationUrl; 168 | } 169 | 170 | @Override 171 | public void onResponse(TweetData response) { 172 | if(response != null){ 173 | mData.addAll(response.getTweets()); 174 | mTweetData = response; 175 | 176 | if(mTweetData.getTweets() != null && mTweetData.getTweets().size() > 0 177 | && mTweetData.getNextPage() != null && !mTweetData.getNextPage().equals("")) { 178 | moreDataToLoad = true; 179 | } 180 | else { 181 | moreDataToLoad = false; 182 | } 183 | 184 | notifyDataSetChanged(); 185 | Log.v(TAG, "New tweets retrieved"); 186 | } 187 | 188 | isLoading = false; 189 | } 190 | 191 | @Override 192 | public void onErrorResponse(VolleyError error) { 193 | Log.e(TAG, "Error retrieving additional tweets: " + error.getMessage()); 194 | isLoading = false; 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.util.Log; 8 | import android.view.View; 9 | import android.widget.AdapterView; 10 | import android.widget.AdapterView.OnItemClickListener; 11 | import android.widget.ListView; 12 | 13 | import com.android.volley.Response; 14 | import com.android.volley.Response.Listener; 15 | import com.android.volley.VolleyError; 16 | import com.captechconsulting.captechbuzz.BuzzArrayAdapter.ViewHolder; 17 | import com.captechconsulting.captechbuzz.model.twitter.TweetData; 18 | import com.captechconsulting.captechbuzz.model.twitter.TwitterManager; 19 | 20 | public class MainActivity extends Activity { 21 | 22 | private final String TAG = getClass().getSimpleName(); 23 | private ListView mListView; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_main); 29 | 30 | mListView = (ListView)findViewById(R.id.buzzListView); 31 | } 32 | 33 | @Override 34 | protected void onResume() { 35 | super.onResume(); 36 | 37 | if(mListView.getAdapter() == null) { 38 | // Get the first page 39 | TwitterManager.getInstance().getDefaultHashtagTweets(createMyReqSuccessListener(), createMyReqErrorListener(), null, 1); 40 | } 41 | 42 | mListView.setOnItemClickListener(new OnItemClickListener() { 43 | 44 | @Override 45 | public void onItemClick(AdapterView parent, View view, int position, 46 | long id) { 47 | ViewHolder holder = (ViewHolder)view.getTag(); 48 | Log.v(TAG, "Go to url " + holder.destinationUrl); 49 | if(holder.destinationUrl != null){ 50 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(holder.destinationUrl)); 51 | startActivity(intent); 52 | } 53 | 54 | } 55 | }); 56 | 57 | } 58 | 59 | private Listener createMyReqSuccessListener() { 60 | return new Listener() { 61 | @Override 62 | public void onResponse(TweetData response) { 63 | Log.v(TAG, "Tweet data loaded"); 64 | mListView.setAdapter(new BuzzArrayAdapter(MainActivity.this, response)); 65 | } 66 | }; 67 | } 68 | 69 | private Response.ErrorListener createMyReqErrorListener() { 70 | return new Response.ErrorListener() { 71 | @Override 72 | public void onErrorResponse(VolleyError error) { 73 | Log.e(TAG, "Tweet data failed to load"); 74 | } 75 | }; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz; 2 | 3 | import com.captechconsulting.captechbuzz.model.RequestManager; 4 | import com.captechconsulting.captechbuzz.model.images.ImageCacheManager; 5 | import com.captechconsulting.captechbuzz.model.images.ImageCacheManager.CacheType; 6 | 7 | import android.app.Application; 8 | import android.graphics.Bitmap.CompressFormat; 9 | 10 | /** 11 | * Example application for adding an L1 image cache to Volley. 12 | * 13 | * @author Trey Robinson 14 | * 15 | */ 16 | public class MainApplication extends Application { 17 | 18 | private static int DISK_IMAGECACHE_SIZE = 1024*1024*10; 19 | private static CompressFormat DISK_IMAGECACHE_COMPRESS_FORMAT = CompressFormat.PNG; 20 | private static int DISK_IMAGECACHE_QUALITY = 100; //PNG is lossless so quality is ignored but must be provided 21 | 22 | @Override 23 | public void onCreate() { 24 | super.onCreate(); 25 | 26 | init(); 27 | } 28 | 29 | /** 30 | * Intialize the request manager and the image cache 31 | */ 32 | private void init() { 33 | RequestManager.init(this); 34 | createImageCache(); 35 | } 36 | 37 | /** 38 | * Create the image cache. Uses Memory Cache by default. Change to Disk for a Disk based LRU implementation. 39 | */ 40 | private void createImageCache(){ 41 | ImageCacheManager.getInstance().init(this, 42 | this.getPackageCodePath() 43 | , DISK_IMAGECACHE_SIZE 44 | , DISK_IMAGECACHE_COMPRESS_FORMAT 45 | , DISK_IMAGECACHE_QUALITY 46 | , CacheType.MEMORY); 47 | } 48 | } -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/GsonRequest.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | 5 | import com.android.volley.NetworkResponse; 6 | import com.android.volley.ParseError; 7 | import com.android.volley.Request; 8 | import com.android.volley.Response; 9 | import com.android.volley.Response.ErrorListener; 10 | import com.android.volley.Response.Listener; 11 | import com.android.volley.toolbox.HttpHeaderParser; 12 | import com.google.gson.Gson; 13 | import com.google.gson.JsonSyntaxException; 14 | 15 | /** 16 | * Wrapper for Volley requests to facilitate parsing of json responses. 17 | * 18 | * @param 19 | */ 20 | public class GsonRequest extends Request{ 21 | 22 | /** 23 | * Gson parser 24 | */ 25 | private final Gson mGson; 26 | 27 | /** 28 | * Class type for the response 29 | */ 30 | private final Class mClass; 31 | 32 | 33 | /** 34 | * Callback for response delivery 35 | */ 36 | private final Listener mListener; 37 | 38 | /** 39 | * @param method 40 | * Request type.. Method.GET etc 41 | * @param url 42 | * path for the requests 43 | * @param objectClass 44 | * expected class type for the response. Used by gson for serialization. 45 | * @param listener 46 | * handler for the response 47 | * @param errorListener 48 | * handler for errors 49 | */ 50 | public GsonRequest(int method 51 | , String url 52 | , Class objectClass 53 | , Listener listener 54 | , ErrorListener errorListener) { 55 | 56 | super(method, url, errorListener); 57 | this.mClass = objectClass; 58 | this.mListener = listener; 59 | mGson = new Gson(); 60 | 61 | } 62 | 63 | @Override 64 | protected Response parseNetworkResponse(NetworkResponse response) { 65 | try { 66 | String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 67 | return Response.success(mGson.fromJson(json, mClass), 68 | HttpHeaderParser.parseCacheHeaders(response)); 69 | } catch (UnsupportedEncodingException e) { 70 | return Response.error(new ParseError(e)); 71 | } catch (JsonSyntaxException e) { 72 | return Response.error(new ParseError(e)); 73 | } 74 | } 75 | 76 | @Override 77 | protected void deliverResponse(T response) { 78 | mListener.onResponse(response); 79 | 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/RequestManager.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model; 2 | 3 | import com.android.volley.RequestQueue; 4 | import com.android.volley.toolbox.Volley; 5 | 6 | import android.content.Context; 7 | 8 | /** 9 | * Manager for the queue 10 | * 11 | * @author Trey Robinson 12 | * 13 | */ 14 | public class RequestManager { 15 | 16 | /** 17 | * the queue :-) 18 | */ 19 | private static RequestQueue mRequestQueue; 20 | 21 | /** 22 | * Nothing to see here. 23 | */ 24 | private RequestManager() { 25 | // no instances 26 | } 27 | 28 | /** 29 | * @param context 30 | * application context 31 | */ 32 | public static void init(Context context) { 33 | mRequestQueue = Volley.newRequestQueue(context); 34 | } 35 | 36 | /** 37 | * @return 38 | * instance of the queue 39 | * @throws 40 | * IllegalStatException if init has not yet been called 41 | */ 42 | public static RequestQueue getRequestQueue() { 43 | if (mRequestQueue != null) { 44 | return mRequestQueue; 45 | } else { 46 | throw new IllegalStateException("Not initialized"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/images/BitmapLruImageCache.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model.images; 2 | 3 | import com.android.volley.toolbox.ImageLoader.ImageCache; 4 | 5 | import android.graphics.Bitmap; 6 | import android.support.v4.util.LruCache; 7 | import android.util.Log; 8 | 9 | /** 10 | * Basic LRU Memory cache. 11 | * 12 | * @author Trey Robinson 13 | * 14 | */ 15 | public class BitmapLruImageCache extends LruCache implements ImageCache{ 16 | 17 | private final String TAG = this.getClass().getSimpleName(); 18 | 19 | public BitmapLruImageCache(int maxSize) { 20 | super(maxSize); 21 | } 22 | 23 | @Override 24 | protected int sizeOf(String key, Bitmap value) { 25 | return value.getRowBytes() * value.getHeight(); 26 | } 27 | 28 | @Override 29 | public Bitmap getBitmap(String url) { 30 | Log.v(TAG, "Retrieved item from Mem Cache"); 31 | return get(url); 32 | } 33 | 34 | @Override 35 | public void putBitmap(String url, Bitmap bitmap) { 36 | Log.v(TAG, "Added item to Mem Cache"); 37 | put(url, bitmap); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/images/DiskLruImageCache.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model.images; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.BufferedOutputStream; 5 | import java.io.File; 6 | import java.io.FileNotFoundException; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | 11 | import android.content.Context; 12 | import android.graphics.Bitmap; 13 | import android.graphics.Bitmap.CompressFormat; 14 | import android.graphics.BitmapFactory; 15 | import android.util.Log; 16 | 17 | import com.android.volley.toolbox.ImageLoader.ImageCache; 18 | import com.captechconsulting.captechbuzz.BuildConfig; 19 | import com.jakewharton.disklrucache.DiskLruCache; 20 | 21 | /** 22 | * Implementation of DiskLruCache by Jake Wharton 23 | * modified from http://stackoverflow.com/questions/10185898/using-disklrucache-in-android-4-0-does-not-provide-for-opencache-method 24 | */ 25 | public class DiskLruImageCache implements ImageCache { 26 | 27 | private DiskLruCache mDiskCache; 28 | private CompressFormat mCompressFormat = CompressFormat.JPEG; 29 | private static int IO_BUFFER_SIZE = 8*1024; 30 | private int mCompressQuality = 70; 31 | private static final int APP_VERSION = 1; 32 | private static final int VALUE_COUNT = 1; 33 | 34 | public DiskLruImageCache(Context context,String uniqueName, int diskCacheSize, 35 | CompressFormat compressFormat, int quality ) { 36 | try { 37 | final File diskCacheDir = getDiskCacheDir(context, uniqueName ); 38 | mDiskCache = DiskLruCache.open( diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize ); 39 | mCompressFormat = compressFormat; 40 | mCompressQuality = quality; 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | 46 | private boolean writeBitmapToFile(Bitmap bitmap, DiskLruCache.Editor editor ) 47 | throws IOException, FileNotFoundException { 48 | OutputStream out = null; 49 | try { 50 | out = new BufferedOutputStream( editor.newOutputStream( 0 ), IO_BUFFER_SIZE ); 51 | return bitmap.compress( mCompressFormat, mCompressQuality, out ); 52 | } finally { 53 | if ( out != null ) { 54 | out.close(); 55 | } 56 | } 57 | } 58 | 59 | private File getDiskCacheDir(Context context, String uniqueName) { 60 | 61 | final String cachePath = context.getCacheDir().getPath(); 62 | return new File(cachePath + File.separator + uniqueName); 63 | } 64 | 65 | @Override 66 | public void putBitmap( String key, Bitmap data ) { 67 | 68 | DiskLruCache.Editor editor = null; 69 | try { 70 | editor = mDiskCache.edit( key ); 71 | if ( editor == null ) { 72 | return; 73 | } 74 | 75 | if( writeBitmapToFile( data, editor ) ) { 76 | mDiskCache.flush(); 77 | editor.commit(); 78 | if ( BuildConfig.DEBUG ) { 79 | Log.d( "cache_test_DISK_", "image put on disk cache " + key ); 80 | } 81 | } else { 82 | editor.abort(); 83 | if ( BuildConfig.DEBUG ) { 84 | Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key ); 85 | } 86 | } 87 | } catch (IOException e) { 88 | if ( BuildConfig.DEBUG ) { 89 | Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key ); 90 | } 91 | try { 92 | if ( editor != null ) { 93 | editor.abort(); 94 | } 95 | } catch (IOException ignored) { 96 | } 97 | } 98 | 99 | } 100 | 101 | @Override 102 | public Bitmap getBitmap( String key ) { 103 | 104 | Bitmap bitmap = null; 105 | DiskLruCache.Snapshot snapshot = null; 106 | try { 107 | 108 | snapshot = mDiskCache.get( key ); 109 | if ( snapshot == null ) { 110 | return null; 111 | } 112 | final InputStream in = snapshot.getInputStream( 0 ); 113 | if ( in != null ) { 114 | final BufferedInputStream buffIn = 115 | new BufferedInputStream( in, IO_BUFFER_SIZE ); 116 | bitmap = BitmapFactory.decodeStream( buffIn ); 117 | } 118 | } catch ( IOException e ) { 119 | e.printStackTrace(); 120 | } finally { 121 | if ( snapshot != null ) { 122 | snapshot.close(); 123 | } 124 | } 125 | 126 | if ( BuildConfig.DEBUG ) { 127 | Log.d( "cache_test_DISK_", bitmap == null ? "" : "image read from disk " + key); 128 | } 129 | 130 | return bitmap; 131 | 132 | } 133 | 134 | public boolean containsKey( String key ) { 135 | 136 | boolean contained = false; 137 | DiskLruCache.Snapshot snapshot = null; 138 | try { 139 | snapshot = mDiskCache.get( key ); 140 | contained = snapshot != null; 141 | } catch (IOException e) { 142 | e.printStackTrace(); 143 | } finally { 144 | if ( snapshot != null ) { 145 | snapshot.close(); 146 | } 147 | } 148 | 149 | return contained; 150 | 151 | } 152 | 153 | public void clearCache() { 154 | if ( BuildConfig.DEBUG ) { 155 | Log.d( "cache_test_DISK_", "disk cache CLEARED"); 156 | } 157 | try { 158 | mDiskCache.delete(); 159 | } catch ( IOException e ) { 160 | e.printStackTrace(); 161 | } 162 | } 163 | 164 | public File getCacheFolder() { 165 | return mDiskCache.getDirectory(); 166 | } 167 | 168 | 169 | 170 | 171 | 172 | } 173 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/images/ImageCacheManager.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model.images; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Bitmap.CompressFormat; 6 | import android.os.AsyncTask; 7 | 8 | import com.android.volley.toolbox.ImageLoader; 9 | import com.android.volley.toolbox.ImageLoader.ImageCache; 10 | import com.android.volley.toolbox.ImageLoader.ImageListener; 11 | import com.captechconsulting.captechbuzz.model.RequestManager; 12 | 13 | /** 14 | * Implementation of volley's ImageCache interface. This manager tracks the application image loader and cache. 15 | * 16 | * Volley recommends an L1 non-blocking cache which is the default MEMORY CacheType. 17 | * @author Trey Robinson 18 | * 19 | */ 20 | public class ImageCacheManager{ 21 | 22 | /** 23 | * Volley recommends in-memory L1 cache but both a disk and memory cache are provided. 24 | * Volley includes a L2 disk cache out of the box but you can technically use a disk cache as an L1 cache provided 25 | * you can live with potential i/o blocking. 26 | * 27 | */ 28 | public enum CacheType { 29 | DISK 30 | , MEMORY 31 | } 32 | 33 | private static ImageCacheManager mInstance; 34 | 35 | /** 36 | * Volley image loader 37 | */ 38 | private ImageLoader mImageLoader; 39 | 40 | /** 41 | * Image cache implementation 42 | */ 43 | private ImageCache mImageCache; 44 | 45 | /** 46 | * @return 47 | * instance of the cache manager 48 | */ 49 | public static ImageCacheManager getInstance(){ 50 | if(mInstance == null) 51 | mInstance = new ImageCacheManager(); 52 | 53 | return mInstance; 54 | } 55 | 56 | /** 57 | * Initializer for the manager. Must be called prior to use. 58 | * 59 | * @param context 60 | * application context 61 | * @param uniqueName 62 | * name for the cache location 63 | * @param cacheSize 64 | * max size for the cache 65 | * @param compressFormat 66 | * file type compression format. 67 | * @param quality 68 | */ 69 | public void init(Context context, String uniqueName, int cacheSize, CompressFormat compressFormat, int quality, CacheType type){ 70 | switch (type) { 71 | case DISK: 72 | mImageCache= new DiskLruImageCache(context, uniqueName, cacheSize, compressFormat, quality); 73 | break; 74 | case MEMORY: 75 | mImageCache = new BitmapLruImageCache(cacheSize); 76 | default: 77 | mImageCache = new BitmapLruImageCache(cacheSize); 78 | break; 79 | } 80 | 81 | mImageLoader = new ImageLoader(RequestManager.getRequestQueue(), mImageCache); 82 | } 83 | 84 | public Bitmap getBitmap(String url) { 85 | try { 86 | return mImageCache.getBitmap(createKey(url)); 87 | } catch (NullPointerException e) { 88 | throw new IllegalStateException("Disk Cache Not initialized"); 89 | } 90 | } 91 | 92 | public void putBitmap(String url, Bitmap bitmap) { 93 | try { 94 | mImageCache.putBitmap(createKey(url), bitmap); 95 | } catch (NullPointerException e) { 96 | throw new IllegalStateException("Disk Cache Not initialized"); 97 | } 98 | } 99 | 100 | 101 | /** 102 | * Executes and image load 103 | * @param url 104 | * location of image 105 | * @param listener 106 | * Listener for completion 107 | */ 108 | public void getImage(String url, ImageListener listener){ 109 | mImageLoader.get(url, listener); 110 | } 111 | 112 | /** 113 | * @return 114 | * instance of the image loader 115 | */ 116 | public ImageLoader getImageLoader() { 117 | return mImageLoader; 118 | } 119 | 120 | /** 121 | * Creates a unique cache key based on a url value 122 | * @param url 123 | * url to be used in key creation 124 | * @return 125 | * cache key value 126 | */ 127 | private String createKey(String url){ 128 | return String.valueOf(url.hashCode()); 129 | } 130 | 131 | 132 | } 133 | 134 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/twitter/Tweet.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model.twitter; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | import java.util.Locale; 7 | 8 | import com.google.gson.annotations.SerializedName; 9 | 10 | public class Tweet { 11 | 12 | private final static String TWEET_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss Z"; 13 | private static final SimpleDateFormat sdf = new SimpleDateFormat(TWEET_DATE_FORMAT, Locale.US); 14 | static { 15 | sdf.setLenient(true); 16 | } 17 | 18 | @SerializedName("from_user") 19 | private final String username; 20 | 21 | 22 | @SerializedName("text") 23 | private final String message; 24 | 25 | @SerializedName("profile_image_url") 26 | private final String userImageUrl; 27 | 28 | @SerializedName("created_at") 29 | private String createdAt; 30 | 31 | @SerializedName("id") 32 | private String tweetId; 33 | 34 | private Date createdDate; 35 | 36 | public Tweet(String username, String message, String userImageUrl){ 37 | this.username = username; 38 | this.message = message; 39 | this.userImageUrl = userImageUrl; 40 | } 41 | 42 | public String getUsername() { 43 | return username; 44 | } 45 | 46 | public String getMessage() { 47 | return message; 48 | } 49 | 50 | public String getUserImageUrl() { 51 | return userImageUrl; 52 | } 53 | 54 | public String getCreatedAt() { 55 | return createdAt; 56 | } 57 | 58 | public String getDestinationUrl() { 59 | return "https://twitter.com/" + username + "/status/" + tweetId; 60 | } 61 | 62 | public Date getCreatedDate(){ 63 | if(createdDate == null){ 64 | try { 65 | createdDate = sdf.parse(createdAt); 66 | } catch (ParseException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | return createdDate; 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/twitter/TweetData.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model.twitter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | public class TweetData { 9 | @SerializedName("completed_in") 10 | private double completedIn; 11 | 12 | @SerializedName("max_id") 13 | private long maxId; 14 | 15 | @SerializedName("max_id_str") 16 | private String maxIdStr; 17 | 18 | @SerializedName("next_page") 19 | private String nextPage; 20 | 21 | @SerializedName("page") 22 | private int page; 23 | 24 | @SerializedName("query") 25 | private String query; 26 | 27 | @SerializedName("refresh_url") 28 | private String refresh_url; 29 | 30 | @SerializedName("results") 31 | private List tweets = new ArrayList(); 32 | 33 | public TweetData(double completedIn, long maxId, String maxIdStr, 34 | String nextPage, int page, String query, String refresh_url, 35 | List tweets) { 36 | super(); 37 | this.completedIn = completedIn; 38 | this.maxId = maxId; 39 | this.maxIdStr = maxIdStr; 40 | this.nextPage = nextPage; 41 | this.page = page; 42 | this.query = query; 43 | this.refresh_url = refresh_url; 44 | this.tweets = tweets; 45 | } 46 | 47 | public double getCompletedIn() { 48 | return completedIn; 49 | } 50 | 51 | public long getMaxId() { 52 | return maxId; 53 | } 54 | 55 | public String getMaxIdStr() { 56 | return maxIdStr; 57 | } 58 | 59 | public String getNextPage() { 60 | return nextPage; 61 | } 62 | 63 | public int getPage() { 64 | return page; 65 | } 66 | 67 | public String getQuery() { 68 | return query; 69 | } 70 | 71 | public String getRefresh_url() { 72 | return refresh_url; 73 | } 74 | 75 | public List getTweets() { 76 | return tweets; 77 | } 78 | 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /CaptechBuzz/src/com/captechconsulting/captechbuzz/model/twitter/TwitterManager.java: -------------------------------------------------------------------------------- 1 | package com.captechconsulting.captechbuzz.model.twitter; 2 | 3 | import android.net.Uri; 4 | import android.util.Log; 5 | 6 | import com.android.volley.Request.Method; 7 | import com.android.volley.Response.ErrorListener; 8 | import com.android.volley.Response.Listener; 9 | import com.captechconsulting.captechbuzz.model.GsonRequest; 10 | import com.captechconsulting.captechbuzz.model.RequestManager; 11 | 12 | public class TwitterManager { 13 | 14 | private final String TAG = getClass().getSimpleName(); 15 | private static TwitterManager mInstance; 16 | 17 | private static String TWITTER_BASE = "http://search.twitter.com/search.json"; 18 | private static String TWITTER_DEFAULT_SEARCH_TERM = "CapTech"; 19 | private static String TWITTER_QUERY = "q"; 20 | private static String TWITTER_INCLUDE_ENTITIES = "include_entities"; 21 | private static String TWITTER_MAX_ID = "max_id"; 22 | private static String TWITTER_RESULTS_PER_PAGE = "rpp"; 23 | private static String TWITTER_PAGE_NUM = "page"; 24 | public static int TWITTER_DEFAULT_PAGE_SIZE = 10; 25 | 26 | public static TwitterManager getInstance(){ 27 | if(mInstance == null) { 28 | mInstance = new TwitterManager(); 29 | } 30 | 31 | return mInstance; 32 | } 33 | 34 | public void getDefaultHashtagTweets(Listener listener, ErrorListener errorListener, String maxId, int pageNum){ 35 | getTweetForHashtag(listener, errorListener, maxId, TWITTER_DEFAULT_SEARCH_TERM, TWITTER_DEFAULT_PAGE_SIZE, pageNum); 36 | } 37 | 38 | public void getTweetForHashtag(Listener listener, ErrorListener errorListener, String maxId, String hashtag, int pageSize, int pageNum){ 39 | 40 | Uri.Builder uriBuilder = Uri.parse(TWITTER_BASE).buildUpon() 41 | .appendQueryParameter(TWITTER_QUERY, hashtag) 42 | .appendQueryParameter(TWITTER_INCLUDE_ENTITIES, "true") 43 | .appendQueryParameter(TWITTER_RESULTS_PER_PAGE, "" + pageSize) 44 | .appendQueryParameter(TWITTER_PAGE_NUM, "" + pageNum); 45 | 46 | if(maxId != null) { 47 | uriBuilder.appendQueryParameter(TWITTER_MAX_ID, maxId); 48 | } 49 | 50 | String uri = uriBuilder.build().toString(); 51 | Log.i(TAG, "getTweetForHashtag: uri = " + uri); 52 | 53 | GsonRequest request = new GsonRequest(Method.GET 54 | , uri 55 | , TweetData.class 56 | , listener 57 | , errorListener); 58 | 59 | Log.v(TAG, request.toString()); 60 | RequestManager.getRequestQueue().add(request); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /CaptechBuzz/tmp/cached-robolectric-classes.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/CaptechBuzz/tmp/cached-robolectric-classes.jar -------------------------------------------------------------------------------- /LICENSE-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | LoginAndSignupTutorial/LICENSE-2.0.txt at master · rdrobinson3/LoginAndSignupTutorial 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 | 65 | 66 | 67 | 68 | 69 |
70 |
71 | 72 | 73 | 74 | 75 | 76 |
77 | 78 | 79 | 80 | 81 |
82 | 83 | 84 |
85 |
86 | 87 | 88 | 94 | 95 | 96 | 97 |
98 | 99 | This repository 100 | 101 | 102 |
103 |
104 | 105 |
106 | 107 | 108 |
This repository
109 |
110 | 111 |
112 | 113 | 114 |
All repositories
115 |
116 | 117 |
118 |
119 |
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
129 | 130 |
131 | 137 |
138 | 139 | 140 | 141 | 142 | 143 | 170 | 171 | 172 | 187 | 188 | 189 | 190 |
191 |
192 | 193 | 194 | 195 | 196 | 197 | 198 |
199 |
200 | 201 |
202 |
203 |
204 | 205 | 206 |
    207 | 208 |
  • 209 | Pull Request 210 |
  • 211 | 212 |
  • 213 |
    214 | 215 |
    216 | 217 | 218 | 219 | Unwatch 220 | 221 | 222 | 223 |
    224 |
    225 |
    226 | Notification status 227 | 228 |
    229 | 230 |
    231 | 232 |
    233 | 234 |
    235 | 236 |

    Not watching

    237 | You only receive notifications for discussions in which you participate or are @mentioned. 238 | 239 | 240 | Watch 241 | 242 |
    243 |
    244 | 245 |
    246 | 247 |
    248 | 249 |

    Watching

    250 | You receive notifications for all discussions in this repository. 251 | 252 | 253 | Unwatch 254 | 255 |
    256 |
    257 | 258 |
    259 | 260 |
    261 | 262 |

    Ignoring

    263 | You do not receive any notifications for discussions in this repository. 264 | 265 | 266 | Stop ignoring 267 | 268 |
    269 |
    270 | 271 |
    272 | 273 |
    274 |
    275 |
    276 | 277 |
    278 |
  • 279 | 280 |
  • 281 | 282 | 283 | Unstar 284 | 285 | 286 | 287 | Star 288 | 289 | 290 |
  • 291 | 292 |
  • 293 | 294 | 295 | Fork 296 | 297 | 298 |
  • 299 | 300 | 301 |
302 | 303 |

304 | public 305 | 306 | 307 | / 310 | LoginAndSignupTutorial 311 |

312 |
313 | 314 | 315 | 333 | 334 |
335 | 336 | 337 | 340 | 341 | 342 |
343 | 344 | 345 |
346 | 347 | 348 | branch: 349 | master 350 | 351 | 352 |
353 | 354 |
355 |
356 | Switch branches/tags 357 | 358 |
359 | 360 |
361 |
362 | 363 |
364 |
365 | 373 |
374 |
375 | 376 |
377 | 378 |
379 | 380 |
381 | 382 | master 383 |
384 |
385 | 386 |
387 | 388 | 389 |
390 |

Create branch:

391 | from ‘master’ 392 |
393 | 394 | 395 | 396 |
397 | 398 |
399 | 400 | 401 |
402 |
403 | 404 |
405 | 406 |
Nothing to show
407 | 408 |
409 | 410 |
411 |
412 |
413 | 414 |
415 | 416 | 421 | 422 |
423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 |
431 |
432 | 433 |
434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 |
442 |
443 | 444 | 445 | 446 | 449 | 450 | 451 | 452 | 453 | 454 |
455 | 456 | 457 | 458 |
459 | Updated Readme 460 |
461 | 462 |
463 |

1 contributor

464 | 465 |
466 | 475 |
476 | 477 | 478 |
479 | 480 |
481 |
482 | 483 |
484 |
485 |
486 |
487 | 488 | file 489 | 207 lines (173 sloc) 490 | 11.441 kb 491 |
492 |
493 |
494 | Edit 497 | Raw 498 | Blame 499 | History 500 |
501 |
502 | 503 |
504 |
505 | 506 | 507 | 716 | 719 | 720 |
508 | 1 509 | 2 510 | 3 511 | 4 512 | 5 513 | 6 514 | 7 515 | 8 516 | 9 517 | 10 518 | 11 519 | 12 520 | 13 521 | 14 522 | 15 523 | 16 524 | 17 525 | 18 526 | 19 527 | 20 528 | 21 529 | 22 530 | 23 531 | 24 532 | 25 533 | 26 534 | 27 535 | 28 536 | 29 537 | 30 538 | 31 539 | 32 540 | 33 541 | 34 542 | 35 543 | 36 544 | 37 545 | 38 546 | 39 547 | 40 548 | 41 549 | 42 550 | 43 551 | 44 552 | 45 553 | 46 554 | 47 555 | 48 556 | 49 557 | 50 558 | 51 559 | 52 560 | 53 561 | 54 562 | 55 563 | 56 564 | 57 565 | 58 566 | 59 567 | 60 568 | 61 569 | 62 570 | 63 571 | 64 572 | 65 573 | 66 574 | 67 575 | 68 576 | 69 577 | 70 578 | 71 579 | 72 580 | 73 581 | 74 582 | 75 583 | 76 584 | 77 585 | 78 586 | 79 587 | 80 588 | 81 589 | 82 590 | 83 591 | 84 592 | 85 593 | 86 594 | 87 595 | 88 596 | 89 597 | 90 598 | 91 599 | 92 600 | 93 601 | 94 602 | 95 603 | 96 604 | 97 605 | 98 606 | 99 607 | 100 608 | 101 609 | 102 610 | 103 611 | 104 612 | 105 613 | 106 614 | 107 615 | 108 616 | 109 617 | 110 618 | 111 619 | 112 620 | 113 621 | 114 622 | 115 623 | 116 624 | 117 625 | 118 626 | 119 627 | 120 628 | 121 629 | 122 630 | 123 631 | 124 632 | 125 633 | 126 634 | 127 635 | 128 636 | 129 637 | 130 638 | 131 639 | 132 640 | 133 641 | 134 642 | 135 643 | 136 644 | 137 645 | 138 646 | 139 647 | 140 648 | 141 649 | 142 650 | 143 651 | 144 652 | 145 653 | 146 654 | 147 655 | 148 656 | 149 657 | 150 658 | 151 659 | 152 660 | 153 661 | 154 662 | 155 663 | 156 664 | 157 665 | 158 666 | 159 667 | 160 668 | 161 669 | 162 670 | 163 671 | 164 672 | 165 673 | 166 674 | 167 675 | 168 676 | 169 677 | 170 678 | 171 679 | 172 680 | 173 681 | 174 682 | 175 683 | 176 684 | 177 685 | 178 686 | 179 687 | 180 688 | 181 689 | 182 690 | 183 691 | 184 692 | 185 693 | 186 694 | 187 695 | 188 696 | 189 697 | 190 698 | 191 699 | 192 700 | 193 701 | 194 702 | 195 703 | 196 704 | 197 705 | 198 706 | 199 707 | 200 708 | 201 709 | 202 710 | 203 711 | 204 712 | 205 713 | 206 714 | 715 | 717 |

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!) The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

<<<<<<< HEAD
   Copyright [yyyy] [name of copyright owner]
=======
   Copyright 2013 Trey Robinson
>>>>>>> Added apache license.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
718 |
721 |
722 | 723 |
724 |
725 | 726 | 727 | 736 | 737 |
738 |
739 |
740 | 741 | 744 | 745 | 746 |
747 |
748 | 749 |
750 | 751 | 752 |
753 | 754 | 755 | 816 | 817 | 818 |
819 |
820 |
821 | 822 |
823 |
825 |
826 |
827 |
828 |
829 | 838 |
839 | 840 | 841 | 842 |
843 | 844 | Something went wrong with that request. Please try again. 845 | 846 |
847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Volley Image Cache 2 | ===== 3 | 4 | An Android application that demonstrates how to implement a memory based and disk based L1 image cache with the the Volley library. The default implementation uses an in-memory cache (as recommended in the Volley comments) but there is a disk based implementation as well. You can change the implementation by altering the MainApplicatin file and passing in the desired Enum value for the cache type. This code demo has a companion blog post, [Google I/O 2013: Volley Image Cache Tutorial](http://blogs.captechconsulting.com/blog/raymond-robinson/google-io-2013-volley-image-cache-tutorial), which goes over the components and architecture used in this demo. 5 | 6 |

7 | 8 |

-------------------------------------------------------------------------------- /Screenshots/framed_buzzscreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdrobinson3/VolleyImageCacheExample/3d1cc456dc5592b365329fdab9ce7adccbcbd9a4/Screenshots/framed_buzzscreenshot.png --------------------------------------------------------------------------------