aboutsummaryrefslogtreecommitdiffstats
path: root/src/cgeo/geocaching/cgHtmlImg.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cgeo/geocaching/cgHtmlImg.java')
-rw-r--r--src/cgeo/geocaching/cgHtmlImg.java286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/cgeo/geocaching/cgHtmlImg.java b/src/cgeo/geocaching/cgHtmlImg.java
new file mode 100644
index 0000000..023912a
--- /dev/null
+++ b/src/cgeo/geocaching/cgHtmlImg.java
@@ -0,0 +1,286 @@
+package cgeo.geocaching;
+
+import android.app.Activity;
+import android.util.Log;
+import android.text.Html;
+import android.view.Display;
+import android.view.WindowManager;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.entity.BufferedHttpEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+public class cgHtmlImg implements Html.ImageGetter {
+
+ private Activity activity = null;
+ private cgSettings settings = null;
+ private String geocode = null;
+ private boolean placement = true;
+ private int reason = 0;
+ private boolean onlySave = false;
+ private BitmapFactory.Options bfOptions = new BitmapFactory.Options();
+ private Display display = null;
+ private int maxWidth = 0;
+ private int maxHeight = 0;
+ private double ratio = 1.0d;
+ private int width = 0;
+ private int height = 0;
+
+ public cgHtmlImg(Activity activityIn, cgSettings settingsIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn) {
+ activity = activityIn;
+ settings = settingsIn;
+ geocode = geocodeIn;
+ placement = placementIn;
+ reason = reasonIn;
+ onlySave = onlySaveIn;
+
+ bfOptions.inTempStorage = new byte[16 * 1024];
+
+ display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
+ maxWidth = display.getWidth() - 25;
+ maxHeight = display.getHeight() - 25;
+ }
+
+ @Override
+ public BitmapDrawable getDrawable(String url) {
+ Bitmap imagePre = null;
+ String dirName = null;
+ String fileName = null;
+ String fileNameSec = null;
+
+ if (url == null || url.length() == 0) {
+ return null;
+ }
+
+ final String[] urlParts = url.split("\\.");
+ String urlExt = null;
+ if (urlParts.length > 1) {
+ urlExt = "." + urlParts[(urlParts.length - 1)];
+ if (urlExt.length() > 5) {
+ urlExt = "";
+ }
+ } else {
+ urlExt = "";
+ }
+
+ if (geocode != null && geocode.length() > 0) {
+ dirName = settings.getStorage() + geocode + "/";
+ fileName = settings.getStorage() + geocode + "/" + cgBase.md5(url) + urlExt;
+ fileNameSec = settings.getStorageSec() + geocode + "/" + cgBase.md5(url) + urlExt;
+ } else {
+ dirName = settings.getStorage() + "_others/";
+ fileName = settings.getStorage() + "_others/" + cgBase.md5(url) + urlExt;
+ fileNameSec = settings.getStorageSec() + "_others/" + cgBase.md5(url) + urlExt;
+ }
+
+ File dir = null;
+ dir = new File(settings.getStorage());
+ if (dir.exists() == false) {
+ dir.mkdirs();
+ }
+ dir = new File(dirName);
+ if (dir.exists() == false) {
+ dir.mkdirs();
+ }
+ dir = null;
+
+ // load image from cache
+ if (onlySave == false) {
+ try {
+ final Date now = new Date();
+
+ final File file = new File(fileName);
+ if (file.exists() == true) {
+ final long imageSize = file.length();
+
+ // large images will be downscaled on input to save memory
+ if (imageSize > (6 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 48;
+ } else if (imageSize > (4 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 16;
+ } else if (imageSize > (2 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 10;
+ } else if (imageSize > (1 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 6;
+ } else if (imageSize > (0.5 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 2;
+ }
+
+ if (reason > 0 || file.lastModified() > (now.getTime() - (24 * 60 * 60 * 1000))) {
+ imagePre = BitmapFactory.decodeFile(fileName, bfOptions);
+ }
+ }
+
+ if (imagePre == null) {
+ final File fileSec = new File(fileNameSec);
+ if (fileSec.exists() == true) {
+ final long imageSize = fileSec.length();
+
+ // large images will be downscaled on input to save memory
+ if (imageSize > (6 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 48;
+ } else if (imageSize > (4 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 16;
+ } else if (imageSize > (2 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 10;
+ } else if (imageSize > (1 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 6;
+ } else if (imageSize > (0.5 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 2;
+ }
+
+ if (reason > 0 || file.lastModified() > (now.getTime() - (24 * 60 * 60 * 1000))) {
+ imagePre = BitmapFactory.decodeFile(fileNameSec, bfOptions);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.w(cgSettings.tag, "cgHtmlImg.getDrawable (reading cache): " + e.toString());
+ }
+ }
+
+ // download image and save it to the cache
+ if ((imagePre == null && reason == 0) || onlySave == true) {
+ Uri uri = null;
+ HttpClient client = null;
+ HttpGet getMethod = null;
+ HttpResponse httpResponse = null;
+ HttpEntity entity = null;
+ BufferedHttpEntity bufferedEntity = null;
+
+ try {
+ // check if uri is absolute or not, if not attach geocaching.com hostname and scheme
+ uri = Uri.parse(url);
+
+ if (uri.isAbsolute() == false) {
+ url = "http://www.geocaching.com" + url;
+ }
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (parse URL): " + e.toString());
+ }
+
+ if (uri != null) {
+ for (int i = 0; i < 2; i++) {
+ if (i > 0) {
+ Log.w(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1));
+ }
+
+ try {
+ client = new DefaultHttpClient();
+ getMethod = new HttpGet(url);
+ httpResponse = client.execute(getMethod);
+ entity = httpResponse.getEntity();
+ bufferedEntity = new BufferedHttpEntity(entity);
+
+ final long imageSize = bufferedEntity.getContentLength();
+
+ // large images will be downscaled on input to save memory
+ if (imageSize > (6 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 48;
+ } else if (imageSize > (4 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 16;
+ } else if (imageSize > (2 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 10;
+ } else if (imageSize > (1 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 6;
+ } else if (imageSize > (0.5 * 1024 * 1024)) {
+ bfOptions.inSampleSize = 2;
+ }
+
+ if (bufferedEntity != null) {
+ imagePre = BitmapFactory.decodeStream(bufferedEntity.getContent(), null, bfOptions);
+ }
+ if (imagePre != null) {
+ break;
+ }
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (downloading from web): " + e.toString());
+ }
+ }
+ }
+
+ try {
+ // save to memory/SD cache
+ if (bufferedEntity != null) {
+ final InputStream is = (InputStream) bufferedEntity.getContent();
+ final FileOutputStream fos = new FileOutputStream(fileName);
+ try {
+ final byte[] buffer = new byte[4096];
+ int l;
+ while ((l = is.read(buffer)) != -1) {
+ fos.write(buffer, 0, l);
+ }
+ } catch (IOException e) {
+ Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (saving to cache): " + e.toString());
+ } finally {
+ is.close();
+ fos.flush();
+ fos.close();
+ }
+ }
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (saving to cache): " + e.toString());
+ }
+
+ entity = null;
+ bufferedEntity = null;
+ }
+
+ if (onlySave == true) {
+ return null;
+ }
+
+ // get image and return
+ if (imagePre == null) {
+ Log.d(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to obtain image");
+
+ if (placement == false) {
+ imagePre = BitmapFactory.decodeResource(activity.getResources(), R.drawable.image_no_placement);
+ } else {
+ imagePre = BitmapFactory.decodeResource(activity.getResources(), R.drawable.image_not_loaded);
+ }
+ }
+
+ final int imgWidth = imagePre.getWidth();
+ final int imgHeight = imagePre.getHeight();
+
+ if (imgWidth > maxWidth || imgHeight > maxHeight) {
+ if ((maxWidth / imgWidth) > (maxHeight / imgHeight)) {
+ ratio = (double) maxHeight / (double) imgHeight;
+ } else {
+ ratio = (double) maxWidth / (double) imgWidth;
+ }
+
+ width = (int) Math.ceil(imgWidth * ratio);
+ height = (int) Math.ceil(imgHeight * ratio);
+
+ try {
+ imagePre = Bitmap.createScaledBitmap(imagePre, width, height, true);
+ } catch (Exception e) {
+ Log.d(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to scale image");
+ return null;
+ }
+ } else {
+ width = imgWidth;
+ height = imgHeight;
+ }
+
+ final BitmapDrawable image = new BitmapDrawable(imagePre);
+ image.setBounds(new Rect(0, 0, width, height));
+
+ return image;
+ }
+}