diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7cc2748d8..848ad8b0c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -82,5 +82,12 @@
+
+
+
+
+
diff --git a/res/drawable-hdpi/paypal_donate.png b/res/drawable-hdpi/paypal_donate.png
new file mode 100644
index 000000000..5ba389b66
Binary files /dev/null and b/res/drawable-hdpi/paypal_donate.png differ
diff --git a/res/drawable-hdpi/twitter_birdy.png b/res/drawable-hdpi/twitter_birdy.png
new file mode 100644
index 000000000..78cf72055
Binary files /dev/null and b/res/drawable-hdpi/twitter_birdy.png differ
diff --git a/res/drawable-mdpi/paypal_donate.png b/res/drawable-mdpi/paypal_donate.png
new file mode 100644
index 000000000..dffd01b5d
Binary files /dev/null and b/res/drawable-mdpi/paypal_donate.png differ
diff --git a/res/drawable-mdpi/twitter_birdy.png b/res/drawable-mdpi/twitter_birdy.png
new file mode 100644
index 000000000..fb2c9d82e
Binary files /dev/null and b/res/drawable-mdpi/twitter_birdy.png differ
diff --git a/res/layout/dev_card.xml b/res/layout/dev_card.xml
new file mode 100644
index 000000000..897f92731
--- /dev/null
+++ b/res/layout/dev_card.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/developer_preference.xml b/res/layout/developer_preference.xml
deleted file mode 100644
index b0f45eda5..000000000
--- a/res/layout/developer_preference.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 4c8303544..c334b4ee8 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -7,6 +7,7 @@
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 05a4849b3..78ac8de8a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4,6 +4,7 @@
ROM Control
+ User Interface
Cancel
OK
Blank!
@@ -39,7 +40,7 @@
Applications
- Developers
+ The Crew
Android Open Kang Project
AOKP Website
www.aokp.co - Find all newest releases here.
@@ -57,7 +58,16 @@
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YJTUMSBC2TRHS
http://nyan.cat
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5R4DYJLDYDRAU
-
+ http://goo.gl/fRj57
+ https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=HGAN9G5ZJ2AAS&lc=US&item_name=kwes1020¤cy_code=USD&bn=PP%%2dDonationsBF%%3abtn_donateCC_LG%2egif%%3aNonHosted
+ https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=U27ZAWB8995TS
+ http://bit.ly/t7YC5Z
+ https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7FN44KF8XZXFW
+ https://www.paypal.com/cgi-bin/webscr?cmd=_flow&SESSION=U3KYhTz6itHx8bKvx-F79EFVY5sQKKQu9f1ftkJ1pevFN6wdaJLu8yz3Y3e&dispatch=5885d80a13c0db1f8e263663d3faee8d1e83f46a36995b3856cef1e18897ad75
+ https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WEZKU46DAFMSW
+ https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6SY3WH7AZNR7Y
+ https://support.woundedwarriorproject.org/Default.aspx?tsid=66&campaignSource=WEBSITE
+
Enable Volume Panel
Show notification count
@@ -133,8 +143,8 @@
How and when do you want the menu buttons to appear?
Navigation button quantity
Choose the number of navigation buttons
- Nav button transparency
Button %1$s action & icon
+ Nav button transparency
Button %1$s longpress action
Home
Back
diff --git a/res/xml/preference_headers.xml b/res/xml/preference_headers.xml
index 607a66da2..ed13cc03d 100644
--- a/res/xml/preference_headers.xml
+++ b/res/xml/preference_headers.xml
@@ -1,4 +1,13 @@
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/aokp/romcontrol/fragments/About.java b/src/com/aokp/romcontrol/fragments/About.java
index 28f5f9c57..6c3df2f35 100644
--- a/src/com/aokp/romcontrol/fragments/About.java
+++ b/src/com/aokp/romcontrol/fragments/About.java
@@ -5,11 +5,16 @@
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
+import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import com.aokp.romcontrol.AOKPPreferenceFragment;
import com.aokp.romcontrol.R;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
public class About extends AOKPPreferenceFragment {
public static final String TAG = "About";
@@ -29,6 +34,20 @@ public void onCreate(Bundle savedInstanceState) {
mReviewUrl = findPreference("aokp_review");
mIrcUrl = findPreference("aokp_irc");
+ PreferenceGroup devsGroup = (PreferenceGroup) findPreference("devs");
+ ArrayList devs = new ArrayList();
+ for (int i = 0; i < devsGroup.getPreferenceCount(); i++) {
+ devs.add(devsGroup.getPreference(i));
+ }
+ devsGroup.removeAll();
+ devsGroup.setOrderingAsAdded(false);
+ Collections.shuffle(devs);
+ for(int i = 0; i < devs.size(); i++) {
+ Preference p = devs.get(i);
+ p.setOrder(i);
+
+ devsGroup.addPreference(p);
+ }
}
@Override
@@ -37,7 +56,7 @@ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preferen
launchUrl("http://aokp.co/");
} else if (preference == mSourceUrl) {
launchUrl("http://github.com/aokp");
- } else if (preference == mReviewUrl) {
+ } else if (preference == mReviewUrl) {
launchUrl("http://gerrit.aokp.co");
} else if (preference == mIrcUrl) {
launchUrl("http://webchat.freenode.net/?channels=teamkang");
diff --git a/src/com/aokp/romcontrol/widgets/DeveloperPreference.java b/src/com/aokp/romcontrol/widgets/DeveloperPreference.java
index f75ed75d1..ca61c1d88 100644
--- a/src/com/aokp/romcontrol/widgets/DeveloperPreference.java
+++ b/src/com/aokp/romcontrol/widgets/DeveloperPreference.java
@@ -4,51 +4,69 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
import android.preference.Preference;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.aokp.romcontrol.R;
+import com.koushikdutta.urlimageviewhelper.UrlImageViewCallback;
+import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.HttpClientParams;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
public class DeveloperPreference extends Preference {
- TextView mName;
- TextView twitter;
- TextView donateText;
- ImageView icon;
- LinearLayout twitterLayout;
- LinearLayout donateLayout;
- ImageView donateButton;
+ private static final String TAG = "DeveloperPreference";
- String twitterHandle;
- String donateLink;
- String name;
+ private ImageView twitterButton;
+ private ImageView donateButton;
+ private ImageView photoView;
+
+ private TextView devName;
+
+ private String nameDev;
+ private String twitterName;
+ private String donateLink;
public DeveloperPreference(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeveloperPreference);
- twitterHandle = a.getString(R.styleable.DeveloperPreference_twitterHandle);
+ nameDev = a.getString(R.styleable.DeveloperPreference_nameDev);
+ twitterName = a.getString(R.styleable.DeveloperPreference_twitterHandle);
donateLink = a.getString(R.styleable.DeveloperPreference_donateLink);
a.recycle();
-
}
@Override
protected View onCreateView(ViewGroup parent) {
+ super.onCreateView(parent);
- View layout = View.inflate(getContext(), R.layout.developer_preference, null);
+ View layout = View.inflate(getContext(), R.layout.dev_card, null);
- mName = (TextView) layout.findViewById(com.android.internal.R.id.title);
- twitter = (TextView) layout.findViewById(R.id.twitter_handle);
+ twitterButton = (ImageView) layout.findViewById(R.id.twitter_button);
donateButton = (ImageView) layout.findViewById(R.id.donate_button);
- twitterLayout = (LinearLayout) layout.findViewById(R.id.twitter_layout);
- icon = (ImageView) layout.findViewById(R.id.twitter_icon);
+ devName = (TextView) layout.findViewById(R.id.name);
+ photoView = (ImageView) layout.findViewById(R.id.photo);
return layout;
}
@@ -57,33 +75,48 @@ protected View onCreateView(ViewGroup parent) {
protected void onBindView(View view) {
super.onBindView(view);
- twitter.setText(twitterHandle);
- icon.setImageResource(R.drawable.twitter_bird);
-
- if (twitterHandle == null) {
- twitterLayout.setVisibility(View.GONE);
- } else
- this.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ if (donateLink != null) {
+ final OnClickListener openDonate = new OnClickListener() {
@Override
- public boolean onPreferenceClick(Preference preference) {
- Uri uriUrl = Uri.parse("http://twitter.com/#!/" + twitterHandle);
- Intent twitter = new Intent(Intent.ACTION_VIEW, uriUrl);
- getContext().startActivity(twitter);
- return true;
+ public void onClick(View v) {
+ Uri donateURL = Uri.parse(donateLink);
+ final Intent intent = new Intent(Intent.ACTION_VIEW, donateURL);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ getContext().startActivity(intent);
}
- });
+ };
- if (donateLink == null)
+ donateButton.setOnClickListener(openDonate);
+ } else {
donateButton.setVisibility(View.GONE);
- else
- donateButton.setOnClickListener(new View.OnClickListener() {
+ }
+
+ if (twitterName != null) {
+ final OnPreferenceClickListener openTwitter = new OnPreferenceClickListener() {
@Override
- public void onClick(View v) {
- Uri uriUrl = Uri.parse(donateLink);
- Intent donate = new Intent(Intent.ACTION_VIEW, uriUrl);
- getContext().startActivity(donate);
+ public boolean onPreferenceClick(Preference preference) {
+ Uri twitterURL = Uri.parse("http://twitter.com/#!/" + twitterName);
+ final Intent intent = new Intent(Intent.ACTION_VIEW, twitterURL);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ getContext().startActivity(intent);
+ return true;
}
- });
+ };
+
+ // changed to clicking the preference to open twitter
+ // it was a hit or miss to click the twitter bird
+ // twitterButton.setOnClickListener(openTwitter);
+ this.setOnPreferenceClickListener(openTwitter);
+ final String url = "http://api.twitter.com/1/users/profile_image/" + twitterName
+ + "?size=original";
+ UrlImageViewHelper.setUrlDrawable(this.photoView, url, R.drawable.ic_null,
+ UrlImageViewHelper.CACHE_DURATION_ONE_WEEK);
+ } else {
+ twitterButton.setVisibility(View.INVISIBLE);
+ photoView.setVisibility(View.GONE);
+ }
+
+ devName.setText(nameDev);
}
}
diff --git a/src/com/koushikdutta/urlimageviewhelper/SoftReferenceHashTable.java b/src/com/koushikdutta/urlimageviewhelper/SoftReferenceHashTable.java
new file mode 100644
index 000000000..348346afc
--- /dev/null
+++ b/src/com/koushikdutta/urlimageviewhelper/SoftReferenceHashTable.java
@@ -0,0 +1,25 @@
+package com.koushikdutta.urlimageviewhelper;
+
+import java.lang.ref.SoftReference;
+import java.util.Hashtable;
+
+public class SoftReferenceHashTable {
+ Hashtable> mTable = new Hashtable>();
+
+ public V put(K key, V value) {
+ SoftReference old = mTable.put(key, new SoftReference(value));
+ if (old == null)
+ return null;
+ return old.get();
+ }
+
+ public V get(K key) {
+ SoftReference val = mTable.get(key);
+ if (val == null)
+ return null;
+ V ret = val.get();
+ if (ret == null)
+ mTable.remove(key);
+ return ret;
+ }
+}
diff --git a/src/com/koushikdutta/urlimageviewhelper/UrlImageCache.java b/src/com/koushikdutta/urlimageviewhelper/UrlImageCache.java
new file mode 100644
index 000000000..e2aeb869f
--- /dev/null
+++ b/src/com/koushikdutta/urlimageviewhelper/UrlImageCache.java
@@ -0,0 +1,14 @@
+package com.koushikdutta.urlimageviewhelper;
+
+import android.graphics.drawable.Drawable;
+
+public final class UrlImageCache extends SoftReferenceHashTable {
+ private static UrlImageCache mInstance = new UrlImageCache();
+
+ public static UrlImageCache getInstance() {
+ return mInstance;
+ }
+
+ private UrlImageCache() {
+ }
+}
diff --git a/src/com/koushikdutta/urlimageviewhelper/UrlImageViewCallback.java b/src/com/koushikdutta/urlimageviewhelper/UrlImageViewCallback.java
new file mode 100644
index 000000000..39f66615f
--- /dev/null
+++ b/src/com/koushikdutta/urlimageviewhelper/UrlImageViewCallback.java
@@ -0,0 +1,8 @@
+package com.koushikdutta.urlimageviewhelper;
+
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+
+public interface UrlImageViewCallback {
+ void onLoaded(ImageView imageView, Drawable loadedDrawable, String url, boolean loadedFromCache);
+}
diff --git a/src/com/koushikdutta/urlimageviewhelper/UrlImageViewHelper.java b/src/com/koushikdutta/urlimageviewhelper/UrlImageViewHelper.java
new file mode 100644
index 000000000..97119f6e2
--- /dev/null
+++ b/src/com/koushikdutta/urlimageviewhelper/UrlImageViewHelper.java
@@ -0,0 +1,319 @@
+package com.koushikdutta.urlimageviewhelper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.HttpClientParams;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.widget.ImageView;
+
+public final class UrlImageViewHelper {
+ private static final String LOGTAG = "UrlImageViewHelper";
+ public static int copyStream(InputStream input, OutputStream output) throws IOException
+ {
+ byte[] stuff = new byte[1024];
+ int read = 0;
+ int total = 0;
+ while ((read = input.read(stuff)) != -1)
+ {
+ output.write(stuff, 0, read);
+ total += read;
+ }
+ return total;
+ }
+
+ static Resources mResources;
+ static DisplayMetrics mMetrics;
+ private static void prepareResources(Context context) {
+ if (mMetrics != null)
+ return;
+ mMetrics = new DisplayMetrics();
+ Activity act = (Activity)context;
+ act.getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
+ AssetManager mgr = context.getAssets();
+ mResources = new Resources(mgr, mMetrics, context.getResources().getConfiguration());
+ }
+
+ private static BitmapDrawable loadDrawableFromStream(Context context, InputStream stream) {
+ prepareResources(context);
+ final Bitmap bitmap = BitmapFactory.decodeStream(stream);
+ //Log.i(LOGTAG, String.format("Loaded bitmap (%dx%d).", bitmap.getWidth(), bitmap.getHeight()));
+ return new BitmapDrawable(mResources, bitmap);
+ }
+
+ public static final int CACHE_DURATION_INFINITE = Integer.MAX_VALUE;
+ public static final int CACHE_DURATION_ONE_DAY = 1000 * 60 * 60 * 24;
+ public static final int CACHE_DURATION_TWO_DAYS = CACHE_DURATION_ONE_DAY * 2;
+ public static final int CACHE_DURATION_THREE_DAYS = CACHE_DURATION_ONE_DAY * 3;
+ public static final int CACHE_DURATION_FOUR_DAYS = CACHE_DURATION_ONE_DAY * 4;
+ public static final int CACHE_DURATION_FIVE_DAYS = CACHE_DURATION_ONE_DAY * 5;
+ public static final int CACHE_DURATION_SIX_DAYS = CACHE_DURATION_ONE_DAY * 6;
+ public static final int CACHE_DURATION_ONE_WEEK = CACHE_DURATION_ONE_DAY * 7;
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, int defaultResource) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultResource, CACHE_DURATION_THREE_DAYS);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url) {
+ setUrlDrawable(imageView.getContext(), imageView, url, null, CACHE_DURATION_THREE_DAYS, null);
+ }
+
+ public static void loadUrlDrawable(final Context context, final String url) {
+ setUrlDrawable(context, null, url, null, CACHE_DURATION_THREE_DAYS, null);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, Drawable defaultDrawable) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultDrawable, CACHE_DURATION_THREE_DAYS, null);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, int defaultResource, long cacheDurationMs) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultResource, cacheDurationMs);
+ }
+
+ public static void loadUrlDrawable(final Context context, final String url, long cacheDurationMs) {
+ setUrlDrawable(context, null, url, null, cacheDurationMs, null);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, Drawable defaultDrawable, long cacheDurationMs) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultDrawable, cacheDurationMs, null);
+ }
+
+ private static void setUrlDrawable(final Context context, final ImageView imageView, final String url, int defaultResource, long cacheDurationMs) {
+ Drawable d = null;
+ if (defaultResource != 0)
+ d = imageView.getResources().getDrawable(defaultResource);
+ setUrlDrawable(context, imageView, url, d, cacheDurationMs, null);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, int defaultResource, UrlImageViewCallback callback) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultResource, CACHE_DURATION_THREE_DAYS, callback);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, UrlImageViewCallback callback) {
+ setUrlDrawable(imageView.getContext(), imageView, url, null, CACHE_DURATION_THREE_DAYS, callback);
+ }
+
+ public static void loadUrlDrawable(final Context context, final String url, UrlImageViewCallback callback) {
+ setUrlDrawable(context, null, url, null, CACHE_DURATION_THREE_DAYS, callback);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, Drawable defaultDrawable, UrlImageViewCallback callback) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultDrawable, CACHE_DURATION_THREE_DAYS, callback);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, int defaultResource, long cacheDurationMs, UrlImageViewCallback callback) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultResource, cacheDurationMs, callback);
+ }
+
+ public static void loadUrlDrawable(final Context context, final String url, long cacheDurationMs, UrlImageViewCallback callback) {
+ setUrlDrawable(context, null, url, null, cacheDurationMs, callback);
+ }
+
+ public static void setUrlDrawable(final ImageView imageView, final String url, Drawable defaultDrawable, long cacheDurationMs, UrlImageViewCallback callback) {
+ setUrlDrawable(imageView.getContext(), imageView, url, defaultDrawable, cacheDurationMs, callback);
+ }
+
+ private static void setUrlDrawable(final Context context, final ImageView imageView, final String url, int defaultResource, long cacheDurationMs, UrlImageViewCallback callback) {
+ Drawable d = null;
+ if (defaultResource != 0)
+ d = imageView.getResources().getDrawable(defaultResource);
+ setUrlDrawable(context, imageView, url, d, cacheDurationMs, callback);
+ }
+
+ private static boolean isNullOrEmpty(CharSequence s) {
+ return (s == null || s.equals("") || s.equals("null") || s.equals("NULL"));
+ }
+
+ private static boolean mHasCleaned = false;
+
+ public static String getFilenameForUrl(String url) {
+ return "" + url.hashCode() + ".urlimage";
+ }
+
+ private static void cleanup(Context context) {
+ if (mHasCleaned)
+ return;
+ mHasCleaned = true;
+ try {
+ // purge any *.urlimage files over a week old
+ String[] files = context.getFilesDir().list();
+ if (files == null)
+ return;
+ for (String file : files) {
+ if (!file.endsWith(".urlimage"))
+ continue;
+
+ File f = new File(context.getFilesDir().getAbsolutePath() + '/' + file);
+ if (System.currentTimeMillis() > f.lastModified() + CACHE_DURATION_ONE_WEEK)
+ f.delete();
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void setUrlDrawable(final Context context, final ImageView imageView, final String url, final Drawable defaultDrawable, long cacheDurationMs, final UrlImageViewCallback callback) {
+ cleanup(context);
+ // disassociate this ImageView from any pending downloads
+ if (imageView != null)
+ mPendingViews.remove(imageView);
+
+ if (isNullOrEmpty(url)) {
+ if (imageView != null)
+ imageView.setImageDrawable(defaultDrawable);
+ return;
+ }
+
+ final UrlImageCache cache = UrlImageCache.getInstance();
+ Drawable drawable = cache.get(url);
+ if (drawable != null) {
+ //Log.i(LOGTAG, "Cache hit on: " + url);
+ if (imageView != null)
+ imageView.setImageDrawable(drawable);
+ if (callback != null)
+ callback.onLoaded(imageView, drawable, url, true);
+ return;
+ }
+
+ final String filename = getFilenameForUrl(url);
+
+ File file = context.getFileStreamPath(filename);
+ if (file.exists()) {
+ try {
+ if (cacheDurationMs == CACHE_DURATION_INFINITE || System.currentTimeMillis() < file.lastModified() + cacheDurationMs) {
+ //Log.i(LOGTAG, "File Cache hit on: " + url + ". " + (System.currentTimeMillis() - file.lastModified()) + "ms old.");
+ FileInputStream fis = context.openFileInput(filename);
+ drawable = loadDrawableFromStream(context, fis);
+ fis.close();
+ if (imageView != null)
+ imageView.setImageDrawable(drawable);
+ cache.put(url, drawable);
+ if (callback != null)
+ callback.onLoaded(imageView, drawable, url, true);
+ return;
+ }
+ else {
+ //Log.i(LOGTAG, "File cache has expired. Refreshing.");
+ }
+ }
+ catch (Exception ex) {
+ }
+ }
+
+ // null it while it is downloading
+ if (imageView != null)
+ imageView.setImageDrawable(defaultDrawable);
+
+ // since listviews reuse their views, we need to
+ // take note of which url this view is waiting for.
+ // This may change rapidly as the list scrolls or is filtered, etc.
+ //Log.i(LOGTAG, "Waiting for " + url);
+ if (imageView != null)
+ mPendingViews.put(imageView, url);
+
+ ArrayList currentDownload = mPendingDownloads.get(url);
+ if (currentDownload != null) {
+ // Also, multiple vies may be waiting for this url.
+ // So, let's maintain a list of these views.
+ // When the url is downloaded, it sets the imagedrawable for
+ // every view in the list. It needs to also validate that
+ // the imageview is still waiting for this url.
+ if (imageView != null)
+ currentDownload.add(imageView);
+ return;
+ }
+
+ final ArrayList downloads = new ArrayList();
+ if (imageView != null)
+ downloads.add(imageView);
+ mPendingDownloads.put(url, downloads);
+
+ AsyncTask downloader = new AsyncTask() {
+ @Override
+ protected BitmapDrawable doInBackground(Void... params) {
+ AndroidHttpClient client = AndroidHttpClient.newInstance(context.getPackageName());
+ try {
+ HttpGet get = new HttpGet(url);
+ final HttpParams httpParams = new BasicHttpParams();
+ HttpClientParams.setRedirecting(httpParams, true);
+ get.setParams(httpParams);
+ HttpResponse resp = client.execute(get);
+ int status = resp.getStatusLine().getStatusCode();
+ if(status != HttpURLConnection.HTTP_OK){
+// Log.i(LOGTAG, "Couldn't download image from Server: " + url + " Reason: " + resp.getStatusLine().getReasonPhrase() + " / " + status);
+ return null;
+ }
+ HttpEntity entity = resp.getEntity();
+// Log.i(LOGTAG, url + " Image Content Length: " + entity.getContentLength());
+ InputStream is = entity.getContent();
+ FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
+ copyStream(is, fos);
+ fos.close();
+ is.close();
+ FileInputStream fis = context.openFileInput(filename);
+ return loadDrawableFromStream(context, fis);
+ }
+ catch (Exception ex) {
+// Log.e(LOGTAG, "Exception during Image download of " + url, ex);
+ return null;
+ }
+ finally {
+ client.close();
+ }
+ }
+
+ protected void onPostExecute(BitmapDrawable result) {
+ Drawable usableResult = result;
+ if (usableResult == null)
+ usableResult = defaultDrawable;
+ mPendingDownloads.remove(url);
+ cache.put(url, usableResult);
+ for (ImageView iv: downloads) {
+ // validate the url it is waiting for
+ String pendingUrl = mPendingViews.get(iv);
+ if (!url.equals(pendingUrl)) {
+ //Log.i(LOGTAG, "Ignoring out of date request to update view for " + url);
+ continue;
+ }
+ mPendingViews.remove(iv);
+ if (usableResult != null) {
+ final Drawable newImage = usableResult;
+ final ImageView imageView = iv;
+ imageView.setImageDrawable(newImage);
+ if (callback != null)
+ callback.onLoaded(imageView, result, url, false);
+ }
+ }
+ }
+ };
+ downloader.execute();
+ }
+
+ private static Hashtable mPendingViews = new Hashtable();
+ private static Hashtable> mPendingDownloads = new Hashtable>();
+}