diff options
Diffstat (limited to 'src/cgeo/geocaching/cgHtmlImg.java')
| -rw-r--r-- | src/cgeo/geocaching/cgHtmlImg.java | 286 |
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; + } +} |
