@NonNull
    private ImmutableTriple<Bitmap, Metadata, Boolean> loadCachedImage(final Uri uri, final boolean forceKeep, final long lastModified) {

        // An image is considered fresh enough if the image exists and one of those conditions is true:
        //  - forceKeep is true and the image has not been modified in the last 24 hours, to avoid reloading shared images;
        //    with every refreshed cache;
        //  - forceKeep is true and userInitiatedRefresh is false, as shared images are unlikely to change at all;
        //  - userInitiatedRefresh is false and the image has not been modified in the last 24 hours.
        final boolean recentlyModified = lastModified > 0 && lastModified > (System.currentTimeMillis() - (24 * 60 * 60 * 1000));
        final boolean freshEnough = (forceKeep && (recentlyModified || !userInitiatedRefresh)) ||
                (recentlyModified && !userInitiatedRefresh);
        if (freshEnough && onlySave) {
            return ImmutableTriple.of(null, null, true);
        }
        final BitmapFactory.Options bfOptions = new BitmapFactory.Options();
        bfOptions.inTempStorage = new byte[16 * 1024];
        bfOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        setSampleSize(uri, bfOptions);
        final Bitmap image = ImageUtils.readImageFromStream(() -> ContentStorage.get().openForRead(uri), bfOptions, uri);
        if (image == null) {
            return ImmutableTriple.of(null, null, false);
        }
        Metadata metadata = null;
        if (loadMetadata) {
            final InputStream imageStream = ContentStorage.get().openForRead(uri);
            if (imageStream == null) {
                Log.i("Cannot open file from " + uri + " again for metadata, maybe it doesnt exist");
                return ImmutableTriple.of(image, null, true);
            }
            metadata = MetadataUtils.readImageMetadata("[HtmlImage]" + uri, imageStream, true);
        }
        return ImmutableTriple.of(image, metadata, freshEnough);
    }
Load a previously saved image.

@param file      the file on disk
@param forceKeep keep the image if it is there, without checking its freshness
@return a triplet with image in the first component, Metadata in second (only if loadMetadata=true) and
{@code true} in the third component if the image was there and is fresh enough or {@code false} otherwise,
and the image (possibly {@code null} if the third component is {@code false} and the image
could not be loaded, or if the third component is {@code true} and {@code onlySave} is also
{@code true})
main/src/main/java/cgeo/geocaching/network/HtmlImage.java