Browse Source

Cache downloaded images

main
M66B 6 years ago
parent
commit
abee6bacc4
1 changed files with 51 additions and 5 deletions
  1. +51
    -5
      app/src/main/java/eu/faircode/email/FragmentMessage.java

+ 51
- 5
app/src/main/java/eu/faircode/email/FragmentMessage.java View File

@ -57,6 +57,9 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
@ -115,6 +118,8 @@ public class FragmentMessage extends FragmentEx {
private boolean debug; private boolean debug;
private DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); private DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
private static final long CACHE_IMAGE_DURATION = 24 * 3600 * 1000L;
@Override @Override
@Nullable @Nullable
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -380,8 +385,9 @@ public class FragmentMessage extends FragmentEx {
final SimpleTask<Spanned> bodyTask = new SimpleTask<Spanned>() { final SimpleTask<Spanned> bodyTask = new SimpleTask<Spanned>() {
@Override @Override
protected Spanned onLoad(final Context context, final Bundle args) throws Throwable { protected Spanned onLoad(final Context context, final Bundle args) throws Throwable {
final long id = args.getLong("id");
final boolean show_images = args.getBoolean("show_images"); final boolean show_images = args.getBoolean("show_images");
String body = EntityMessage.read(context, args.getLong("id"));
String body = EntityMessage.read(context, id);
args.putInt("size", body.length()); args.putInt("size", body.length());
return Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false), new Html.ImageGetter() { return Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false), new Html.ImageGetter() {
@ -391,22 +397,55 @@ public class FragmentMessage extends FragmentEx {
int px = (int) (24 * scale + 0.5f); int px = (int) (24 * scale + 0.5f);
if (show_images) { if (show_images) {
// Get cache folder
File dir = new File(context.getCacheDir(), "images");
dir.mkdir();
// Cleanup cache
long now = new Date().getTime();
File[] images = dir.listFiles();
if (images != null)
for (File image : images)
if (image.isFile() && image.lastModified() + CACHE_IMAGE_DURATION < now) {
Log.i(Helper.TAG, "Deleting from image cache " + image.getName());
image.delete();
}
// Create unique file name
File file = new File(dir, id + "_" + source.hashCode());
InputStream is = null; InputStream is = null;
FileOutputStream os = null;
try { try {
is = new URL(source).openStream();
// Get input stream
if (file.exists())
is = new FileInputStream(file);
else
is = new URL(source).openStream();
// Decode image from stream
Bitmap bm = BitmapFactory.decodeStream(is); Bitmap bm = BitmapFactory.decodeStream(is);
if (bm == null) if (bm == null)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
// Cache bitmap
if (!file.exists()) {
os = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, os);
}
// Create drawable from bitmap
Drawable d = new BitmapDrawable(context.getResources(), bm); Drawable d = new BitmapDrawable(context.getResources(), bm);
d.setBounds(0, 0, bm.getWidth(), bm.getHeight()); d.setBounds(0, 0, bm.getWidth(), bm.getHeight());
// TODO image caching?
return d; return d;
} catch (Throwable ex) { } catch (Throwable ex) {
// Show warning icon
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Drawable d = context.getResources().getDrawable(R.drawable.baseline_warning_24, context.getTheme()); Drawable d = context.getResources().getDrawable(R.drawable.baseline_warning_24, context.getTheme());
d.setBounds(0, 0, px, px); d.setBounds(0, 0, px, px);
return d; return d;
} finally { } finally {
// Close streams
if (is != null) { if (is != null) {
try { try {
is.close(); is.close();
@ -414,8 +453,16 @@ public class FragmentMessage extends FragmentEx {
Log.w(Helper.TAG, e + "\n" + Log.getStackTraceString(e)); Log.w(Helper.TAG, e + "\n" + Log.getStackTraceString(e));
} }
} }
if (os != null) {
try {
os.close();
} catch (IOException e) {
Log.w(Helper.TAG, e + "\n" + Log.getStackTraceString(e));
}
}
} }
} else { } else {
// Show placeholder icon
args.putBoolean("has_images", true); args.putBoolean("has_images", true);
Drawable d = context.getResources().getDrawable(R.drawable.baseline_image_24, context.getTheme()); Drawable d = context.getResources().getDrawable(R.drawable.baseline_image_24, context.getTheme());
d.setBounds(0, 0, px, px); d.setBounds(0, 0, px, px);
@ -425,7 +472,7 @@ public class FragmentMessage extends FragmentEx {
}, new Html.TagHandler() { }, new Html.TagHandler() {
@Override @Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
// Do nothing
} }
}); });
} }
@ -441,7 +488,6 @@ public class FragmentMessage extends FragmentEx {
grpMessage.setVisibility(View.VISIBLE); grpMessage.setVisibility(View.VISIBLE);
fab.setVisibility(free ? View.GONE : View.VISIBLE); fab.setVisibility(free ? View.GONE : View.VISIBLE);
pbBody.setVisibility(View.GONE); pbBody.setVisibility(View.GONE);
} }
}; };


Loading…
Cancel
Save