Files

The content in this guide refers to the newly released version 3 of the library. You can still access the version 2.x guides here.

Version 2.x is now deprecated. We will continue to support 2.x through November 30, 2017 (End of Support - EOS). If you are currently using 2.x in your apps, you will need to upgrade your apps to 3.x before the EOS date. We have created a migration guide to help you.

You can use Kinvey to store and retrieve binary files of size up to 5TB. Files can be of any format.

The files are automatically enabled for download using a Content Delivery Network (CDN) for massive scale and performance.

Kinvey does not directly serve or accept files. Instead, the Kinvey Files API works by providing a short-lived URL to a third-party cloud storage service from which file(s) can be uploaded or downloaded. Currently, the third-party service used is Google Cloud Storage.

You would typically use the Files API to upload and download:

  • images
  • video files
  • other application-specific files.

Uploading

The library's File API supports uploading a java.io.File directly as well as streaming content from an InputStream.

java.io.File

To upload a file, use kinveyClient.getFileStore(StoreType).upload(). Pass the file content as the first argument, followed by an AsyncUploaderProgressListener<FileMetaData> for callbacks.

import com.kinvey.android.callback.AsyncUploaderProgressListener;

...

java.io.File file = new java.io.File(getFilesDir(), "chicken_fried_waffles.txt");
file.createNewFile();

boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.upload(file, new AsyncUploaderProgressListener<FileMetaData>() {
    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
});

Optionally, you can use a FileMetaData object as the first parameter to save additional metadata. This lets you set the File's unique _id, ACLs, mark files as public, and set any other custom attributes your app may need.

import com.kinvey.java.model.FileMetaData;
...

FileMetaData metadata = new FileMetaData("myFileID");  //create the FileMetaData object
metadata.setPublic(true);  //set the file to be pubicly accesible
metadata.setAcl(new KinveyMetaData.AccessControlList().setGloballyReadable(true)); //allow all users to see this file
metadata.setFileName("chicken_fried_waffles.txt");

java.io.File file = new java.io.File(getFilesDir(), "chicken_fried_waffles.txt");
file.createNewFile();

boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.upload(file, metadata, new AsyncUploaderProgressListener<FileMetaData>() {
    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
});

InputStream

Alternatively you can upload a file from an input stream.

FileInputStream fIn = new FileInputStream(new File ("eats_bacon.mpg"));

boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.upload("myFileID", metadata, new AsyncUploaderProgressListener<FileMetaData>() {
    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
});

You can also provide a FileMetaData object as the first argument when streaming from an InputStream.

import com.kinvey.java.model.FileMetaData;
...

FileInputStream fIn = new FileInputStream(new File ("eats_bacon.mpg"));
FileMetaData metadata = new FileMetaData("myFileID");  //create the FileMetaData object

boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.upload(fIn, metadata, new AsyncUploaderProgressListener<FileMetaData>() {
    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
});

Uploading publicly readable files

Use the method myFileMetaData.setPublic(true) if you want to upload a publicly-readable file. This means that the download link to the file will not expire until you delete the file through Kinvey. If a user uploads a file that you want other users to be able download, you will have to set the gr (globally readable) attribute to true in the _acl (access control list).

import com.kinvey.java.model.FileMetaData;
...

FileMetaData myFileMetaData = new FileMetaData("myFileID");  //create the FileMetaData object
myFileMetaData.setPublic(true);  //set the file to be pubicly accesible
myFileMetaData.setAcl(new KinveyMetaData.AccessControlList().setGloballyReadable(true)); //allow all users to see this file
metadata.setFileName("chicken_fried_waffles.txt");

java.io.File file = new java.io.File(getFilesDir(), "chicken_fried_waffles.txt");
file.createNewFile();

boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.upload(metadata, file, new AsyncUploaderProgressListener<FileMetaData>() {
    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
});

Downloading

For downloading files to an OutputStream, you can open a file output stream, by fileMetaData, then feed the file output stream to the file download.

FileOutputStream fos = new FileOutputStream("mug.png");
FileMetaData fileMetaDataForDownload = new FileMetaData();
fileMetaDataForDownload.setId("myFileID");
boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.download(fileMetaDataForDownload, fos, new AsyncDownloaderProgressListener<FileMetaData>() {

    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpDownloader mediaHttpDownloader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
});

Optionally, you can use a KinveyCachedClientCallback<FileMetaData> as the fives parameter to download file. This lets you get the File from cache. This callback is available only for StoreType.CACHE

FileOutputStream fos = new FileOutputStream("mug.png");
FileMetaData fileMetaDataForDownload = new FileMetaData();
fileMetaDataForDownload.setId("myFileID");
boolean isCancelled = false;
FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.download(fileMetaDataForDownload, fos, new AsyncDownloaderProgressListener<FileMetaData>() {

    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }

    @Override
    public void progressChanged(MediaHttpDownloader mediaHttpDownloader) throws IOException {
        // Place your code here
    }

    @Override
    public void onCancelled() {
        // Place your code here
    }

    @Override
    public boolean isCancelled() {
        return isCancelled;
    }
}, new KinveyCachedClientCallback<FileMetaData>() {
    @Override
    public void onSuccess(FileMetaData fileMetaData) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }
});

MediaPlayer Streaming

You can use the URI in conjunction with Android's MediaPlayer to stream videos or audio files. This has the distinct advantage of not needing to load the entire resource into memory before handing it off to the media player or bitmap factory. This approach saves on both memory usage and battery life, as the file contents are streamed and accessed at the same time.

Query query = new Query();
query = query.equals("_id", "MyFileId");
FileStore fileStore = client.getFileStore(StoreType.CACHE);
fileStore.find(query, new KinveyClientCallback<FileMetaData[]>() {
    @Override
    public void onSuccess(FileMetaData[] fileMetaDatas) {
        MediaPlayer mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setDataSource(fileMetaDatas[0].getDownloadURL());
        mMediaPlayer.prepare();
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        // you have 1 hour from the time getDownloadUrl was initiated to begin downloading
        // with the temporary url
        mMediaPlayer.start();
    }

    @Override
    public void onFailure(Throwable throwable) {
    Log.e(TAG, "error downloading movie.mp4", t);
    }
});

Deleting

You can permanently remove a file using the remove() method.

FileStore fileStore = kinveyClient.getFileStore(StoreType.CACHE);
fileStore.remove(fileMetaData, new KinveyDeleteCallback() {
    @Override
    public void onSuccess(Integer integer) {
        // Place your code here
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Place your error handler here
    }
});
Got a question?