box / box-android-preview-sdk

Box Android Preview SDK
Apache License 2.0
13 stars 10 forks source link

Cache files for offline usage #14

Open rupbhangale opened 7 years ago

rupbhangale commented 7 years ago

I am building the android app which uses box-content and box-preview api's, as box-preview api allows cache policy i want to use that and cache the files for offline purpose. But i can't find any documentation for the same nor the example.

Can anyone help me with how can i use the api to cache the file for offline usage. Also how to read the cached file.

upendrapatil commented 7 years ago

It appears that the android-preview-sdk can only cache thumbnail(for image) and metadata(for files) and not the actual content as opposed to the ios-preview-sdk on ios(as per ios-preview-sdk docs, content caching is possible).Is content caching going to be implemented for android-preview-sdk as well? If already present please provide guidance for implementing same.

doncung commented 6 years ago

Thank you for the input. We will look into making this caching logic public. Currently it is possible through extending BoxApiPreview and overwriting the getOfflineRequests method which is protected. As long as the preview controller passed in matches the one used in the SDK this should let you offline content in advance.

doncung commented 6 years ago

Looking at our code again there is another way to do this by calling BoxPreviewViewPager.getCacheFileRequest(final PreviewController previewController, final BoxFile file) .

upendrapatil commented 6 years ago

Thanks for the reply. We had tried the 2nd approach. But it just cached the preview as mentioned in my earlier comment. We will try the first approach.

doncung commented 6 years ago

Not sure what you mean by actual content. The sdk caching methods are designed to store enough data on a given file so that it can be shown in the preview sdk when offline. It won't necessarily store the original file if that's what you meant.

On Nov 6, 2017 9:49 PM, "upendrapatil" notifications@github.com wrote:

Thanks for the reply. We had tried the 2nd approach. But it just cached the preview as mentioned in my earlier comment. We will try the first approach.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/box/box-android-preview-sdk/issues/14#issuecomment-342382495, or mute the thread https://github.com/notifications/unsubscribe-auth/AAmHYvNz4EM7lbJQNBqSQdzSt71zwQlrks5sz-9kgaJpZM4N_JZa .

upendrapatil commented 6 years ago

Lets say I have an image of 5000x5000.When I use the preview sdk method BoxPreviewViewPager.getCacheFileRequest()..it internally calls BoxPreviewImageFragment.getCachePreviewRequest() which uses 1024 size, while I want the original 5000x5000 image to be cached for preview. Its just an example but I believe that should help clarify what I mean by actual content.

doncung commented 6 years ago

Thanks for clarifying. The reason why we use the 1024 thumbnails is actually to handle this situation as extremely high resolution images will not only be slow to download, but can cause memory/performance issues when displayed. If you are absolutely certain the original image is suitable for display you can implement PreviewController (and Serializable) or extend DefaultPreviewController and implement the download thumbnail method. You can change the implementation of PreviewController in the intent to launch preview activity.

This is the implementation in our DefaultPreviewController for some guidance: private static ConcurrentHashMap<String, BoxFutureTask> CURRENT_THUMBNAIL_DOWNLOADS = new ConcurrentHashMap<String, BoxFutureTask>(); public InputStream downloadThumbnail(final BoxFile boxFile, int minSize) throws BoxException{ BoxFile minInfoFile = boxFile;

    // We must make a request against the server if the provided file does not contain the required fields
    if (boxFile.getSha1() == null || boxFile.getName() == null) {
        minInfoFile = getApiPreview().getInfoRequest(boxFile.getId()).send();
    }
    String thumbnailTag = Integer.toString(minSize);
    File thumbnailFile = null;
    if (minSize >= BoxRequestsPreview.DownloadPreview.SIZE_1024){
        thumbnailFile = getStorage().getCachedPreviewFile(minInfoFile, thumbnailTag);
    } else {
        thumbnailFile = getStorage().getCachedThumbnailFile(minInfoFile, thumbnailTag);
    }
    if (!thumbnailFile.exists() || thumbnailFile.length() == 0){
        BoxFutureTask<BoxDownload> currentDownloadTask = CURRENT_THUMBNAIL_DOWNLOADS.get(thumbnailFile.getAbsolutePath());
        if (currentDownloadTask == null || currentDownloadTask.isDone() || currentDownloadTask.isCancelled()) {
            OutputStream outputStream = null;
            if (minSize >= BoxRequestsPreview.DownloadPreview.SIZE_1024) {
                outputStream = getStorage().createPreviewOutputStream(minInfoFile, thumbnailTag);
            } else {
                outputStream = getStorage().createThumbnailOutputStream(minInfoFile, thumbnailTag);
            }
            // Thumbnail not available and must be requested from the server
            if (MimeTypeHelper.isMultiPagePreviewableExtension(BoxPreviewUtils.getExtension(minInfoFile))) {
                // Thumbnails are not available for text documents, pdfs, so use preview endpoint etc..
                currentDownloadTask = getApiPreview().getDownloadPreviewRequest(outputStream, boxFile.getId(), BoxApiPreview.Extensions.PNG)
                        .setPage(1)
                        .setMinSize(minSize).toTask();
            } else {
                // The thumbnail end point is available immediately so prioritize them.
                currentDownloadTask = getApiPreview().getDownloadThumbnailRequest(outputStream, boxFile.getId())
                        .setMinSize(minSize).toTask();
            }
            CURRENT_THUMBNAIL_DOWNLOADS.put(thumbnailFile.getAbsolutePath(), currentDownloadTask);
            currentDownloadTask.run();
        }
        try {
           BoxResponse response = currentDownloadTask.get();
            if (response.getException() instanceof BoxException){
                throw (BoxException)response.getException();
            }
        } catch (InterruptedException e){
            BoxLogUtils.e("error", e);
            return null;
        } catch (ExecutionException e){
            BoxLogUtils.e("error", e);
            return null;
        } finally {
            CURRENT_THUMBNAIL_DOWNLOADS.remove(thumbnailFile.getAbsolutePath());
        }

    }
    if (minSize >= BoxRequestsPreview.DownloadPreview.SIZE_1024){
        return getStorage().getCachedPreview(minInfoFile,thumbnailTag);
    } else {
        return getStorage().getCachedThumbnail(minInfoFile,thumbnailTag);
    }
}