Skip to content

Instantly share code, notes, and snippets.

@flavienlaurent
Last active December 27, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flavienlaurent/7337127 to your computer and use it in GitHub Desktop.
Save flavienlaurent/7337127 to your computer and use it in GitHub Desktop.
Implementing a DocumentsProvier
import android.database.MatrixCursor;
import android.os.Bundle;
import android.provider.DocumentsContract;
public class DocumentsCursor extends MatrixCursor {
private Bundle mExtras;
public DocumentsCursor(String[] columnNames, int initialCapacity) {
super(columnNames, initialCapacity);
}
public DocumentsCursor(String[] columnNames) {
super(columnNames);
}
public Bundle getExtras() {
if (mExtras == null) {
return super.getExtras();
}
return mExtras;
}
public void setErrorInformation(String errorMessage) {
if (mExtras == null) {
this.mExtras = new Bundle();
mExtras.putString(DocumentsContract.EXTRA_ERROR, errorMessage);
}
}
public void setIsLoading(boolean isLoading) {
if (mExtras == null) {
mExtras = new Bundle();
mExtras.putBoolean(DocumentsContract.EXTRA_LOADING, isLoading);
}
}
}
[...]
@Override
public ParcelFileDescriptor openDocument(final String documentId, String mode, final CancellationSignal signal) throws FileNotFoundException {
File file = fileFromDocumentId(documentId);
if(file.exists()) {
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}
/* really dirty like in Drive app
StrictMode.ThreadPolicy threadpolicy = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy((new StrictMode.ThreadPolicy.Builder()).build());
*/
try {
//blocking download
download(documentId, file, signal);
/*
StrictMode.setThreadPolicy(threadpolicy);
*/
if(file.exists()) {
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}
throw new FileNotFoundException("Failed to open document " + documentId + " and mode " + mode);
} catch (IOException e) {
throw new FileNotFoundException("Failed to open document " + documentId + " and mode " + mode);
}
}
[...]
[...]
@Override
public ParcelFileDescriptor openDocument(final String documentId, String mode, final CancellationSignal signal) throws FileNotFoundException {
try {
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createReliablePipe();
//use the write part of pipe
ParcelFileDescriptor.AutoCloseOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
//1. download and register a listener on cancellation
final DownloadTask task = downloadWithYourHttpLayer(documentId, outputStream);
if(signal != null) {
signal.setOnCancelListener(new CancellationSignal.OnCancelListener() {
@Override
public void onCancel() {
task.cancel();
}
});
}
//or
//2. download and check the signal during the download
downloadWithYourHttpLayer(documentId, outputStream, signal);
//return the read part of pipe
return pipe[0];
} catch (IOException e) {
throw new FileNotFoundException("Failed to open document " + documentId + " in mode " + mode);
}
}
[...]
[...]
private final ConcurrentHashMap<Uri, Boolean> mLoadingUris = new ConcurrentHashMap<Uri, Boolean>();
@Override
public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException {
final DocumentsCursor cursor = new DocumentsCursor(resolveDocumentProjection(projection));
fillChildrenFromLocalCache(parentDocumentId, cursor);
final Uri uri = DocumentsContract.buildChildDocumentsUri(AUTHORITY, parentDocumentId);
Boolean active = mLoadingUris.get(uri);
if(active == null) {
//no loading request for this uri, launch it
mLoadingUris.put(uri, Boolean.TRUE);
cursor.setIsLoading(true);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
fillChildrenFromWeb(parentDocumentId, new OnLoadedListener() {
@Override
public void onLoaded(List<YourItem> childs) {
putChildrenInLocalCache(childs);
//loading request is finished, refresh
mLoadingUris.put(uri, Boolean.FALSE);
getContext().getContentResolver().notifyChange(uri, null);
}
});
} else if(!active) {
//loading request is finished and refreshed
mLoadingUris.remove(uri);
}
return cursor;
}
[...]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment