@@ -145,7 +145,7 @@ private boolean setLegacyBaseFolderByName(String namedSubFolder) {
145145 return true ;
146146 }
147147
148- public void selectBaseDirectoryByType (FileChooserBuilder .BaseFolderPathType baseFolderType ) {
148+ public boolean selectBaseDirectoryByType (FileChooserBuilder .BaseFolderPathType baseFolderType ) {
149149 Context appCtx = FileChooserActivity .getInstance ();
150150 switch (baseFolderType ) {
151151 case BASE_PATH_TYPE_FILES_DIR :
@@ -189,8 +189,9 @@ public void selectBaseDirectoryByType(FileChooserBuilder.BaseFolderPathType base
189189 case BASE_PATH_TYPE_MEDIA_STORE :
190190 case BASE_PATH_EXTERNAL_PROVIDER :
191191 default :
192- return ;
192+ break ;
193193 }
194+ return baseDirPath != null ;
194195 }
195196
196197 public String getCWD () {
@@ -400,6 +401,7 @@ public AssetFileDescriptor openDocumentThumbnail(String documentId, Point sizeHi
400401 if (extDocsProviderStaticInst != null ) {
401402 return extDocsProviderStaticInst .openDocumentThumbnail (documentId , sizeHint , signal );
402403 }
404+ // The document needs to have the flag: FLAG_SUPPORTS_THUMBNAIL ???
403405
404406 final File file = getFileForDocId (documentId );
405407 final ParcelFileDescriptor pfd =
@@ -668,17 +670,21 @@ private File getFileForDocId(String docId) throws FileNotFoundException {
668670 } else {
669671 final String path = docId .substring (splitIndex + 1 );
670672 target = new File (target , path );
671- //Log.i(LOGTAG, "DOCID effective path -> " + target.getAbsolutePath());
672673 if (!target .exists ()) {
673674 throw new FileNotFoundException ("Missing file for " + docId + " at " + target );
674675 }
675676 return target ;
676677 }
677678 }
678679
680+ private long getDocumentSize (String docId ) throws FileNotFoundException {
681+ File docFileRef = getFileForDocId (docId );
682+ return docFileRef .length ();
683+ }
684+
679685 public static final boolean CURSOR_TYPE_IS_ROOT = true ;
680686
681- public static String getDocumentIdForCursorType (MatrixCursor mcResult , boolean cursorType ) {
687+ private static String getDocumentIdForCursorType (MatrixCursor mcResult , boolean cursorType ) {
682688 if (mcResult .getCount () == 0 ) {
683689 return null ;
684690 }
@@ -766,18 +772,22 @@ public String[] getPropertiesOfCurrentRow(MatrixCursor mcResult, boolean cursorT
766772
767773 private static final int BYTE_BUFFER_SIZE = 128 ;
768774
769- public StringBuilder readFileContentsAsString (final String documentId ) {
775+ public StringBuilder readFileContentsAsString (final String documentId , int offset , int maxBytes ) {
776+ if (offset < 0 || maxBytes <= 0 ) {
777+ return null ;
778+ }
770779 try {
771780 ParcelFileDescriptor docDesc = openDocument (documentId , "r+" , null );
772781 FileDescriptor fd = docDesc .getFileDescriptor ();
773782 FileInputStream inputStream = new FileInputStream (fd );
774783 StringBuilder sbuilder = new StringBuilder ();
775784 byte [] byteBuf = new byte [BYTE_BUFFER_SIZE ];
776- int bytesRead = inputStream .read (byteBuf , 0 , BYTE_BUFFER_SIZE );
785+ int bytesRead = inputStream .read (byteBuf , offset , Math . min ( maxBytes , BYTE_BUFFER_SIZE ) );
777786 while (bytesRead > 0 ) {
787+ maxBytes -= bytesRead ;
778788 byte [] bytesReadBuf = Arrays .copyOf (byteBuf , bytesRead );
779789 sbuilder .append (new String (bytesReadBuf ));
780- bytesRead = inputStream .read (byteBuf , 0 , BYTE_BUFFER_SIZE );
790+ bytesRead = inputStream .read (byteBuf , 0 , Math . min ( maxBytes , BYTE_BUFFER_SIZE ) );
781791 }
782792 inputStream .close ();
783793 docDesc .close ();
@@ -791,15 +801,19 @@ public StringBuilder readFileContentsAsString(final String documentId) {
791801 }
792802 }
793803
794- public byte [] readFileContentsAsBytesArray (final String documentId ) {
804+ public byte [] readFileContentsAsByteArray (final String documentId , int offset , int maxBytes ) {
805+ if (offset < 0 || maxBytes <= 0 ) {
806+ return null ;
807+ }
795808 try {
796809 ParcelFileDescriptor docDesc = openDocument (documentId , "r+" , null );
797810 FileDescriptor fd = docDesc .getFileDescriptor ();
798811 FileInputStream inputStream = new FileInputStream (fd );
799812 int actualSize = 0 , bufCapacity = BYTE_BUFFER_SIZE ;
800813 byte [] returnBuf = new byte [BYTE_BUFFER_SIZE ], byteBuf = new byte [BYTE_BUFFER_SIZE ];
801- int bytesRead = inputStream .read (byteBuf , 0 , BYTE_BUFFER_SIZE );
814+ int bytesRead = inputStream .read (byteBuf , offset , Math . min ( maxBytes , BYTE_BUFFER_SIZE ) );
802815 while (bytesRead > 0 ) {
816+ maxBytes -= bytesRead ;
803817 byte [] bytesReadBuf = Arrays .copyOf (byteBuf , bytesRead );
804818 System .arraycopy (returnBuf , actualSize , bytesReadBuf , 0 , bytesRead );
805819 actualSize += bytesRead ;
@@ -809,7 +823,7 @@ public byte[] readFileContentsAsBytesArray(final String documentId) {
809823 System .arraycopy (nextReturnBuf , 0 , returnBuf , 0 , actualSize );
810824 returnBuf = nextReturnBuf ;
811825 }
812- bytesRead = inputStream .read (byteBuf , 0 , BYTE_BUFFER_SIZE );
826+ bytesRead = inputStream .read (byteBuf , 0 , Math . min ( maxBytes , BYTE_BUFFER_SIZE ) );
813827 }
814828 inputStream .close ();
815829 docDesc .close ();
@@ -823,4 +837,108 @@ public byte[] readFileContentsAsBytesArray(final String documentId) {
823837 }
824838 }
825839
840+ /* More robust DocumentsProvider functionality:
841+ * -> Support document creation: https://developer.android.com/guide/topics/providers/create-document-provider#creating
842+ * -> Support document management features: (delete, rename, copy, move, remove)
843+ * https://developer.android.com/guide/topics/providers/create-document-provider#browsing
844+ */
845+
846+ class DocumentPointer {
847+
848+ private BasicFileProvider fpInst ;
849+ private boolean isValid ;
850+ private FileChooserBuilder .BaseFolderPathType baseFolderType ;
851+ private String relativeFolderPathOffset ;
852+ private String absFolderPathOffset ;
853+ private String filePath ; // Should be trimmed relative to the initial base folders
854+ private String documentId ;
855+ private Cursor documentCursorEntry ; // Of size one
856+
857+ private void initializeDefaults () {
858+ fpInst = BasicFileProvider .getInstance ();
859+ if (fpInst == null ) {
860+ throw new FileChooserException .BasicFileProviderException ();
861+ }
862+ isValid = false ;
863+ baseFolderType = null ;
864+ relativeFolderPathOffset = null ;
865+ absFolderPathOffset = null ;
866+ filePath = null ;
867+ documentId = null ;
868+ documentCursorEntry = null ;
869+ }
870+
871+ DocumentPointer (FileChooserBuilder .BaseFolderPathType baseFolderType ) {
872+ initializeDefaults ();
873+ fpInst .resetBaseDirectory ();
874+ isValid = fpInst .selectBaseDirectoryByType (baseFolderType );
875+ this .baseFolderType = baseFolderType ;
876+ }
877+
878+ DocumentPointer (FileChooserBuilder .BaseFolderPathType baseFolderType , String relativeOffsetPath ) {
879+ initializeDefaults ();
880+ fpInst .resetBaseDirectory ();
881+ isValid = fpInst .selectBaseDirectoryByType (baseFolderType );
882+ isValid = isValid && fpInst .enterNextSubfolder (relativeOffsetPath );
883+ this .baseFolderType = baseFolderType ;
884+ this .relativeFolderPathOffset = relativeOffsetPath ;
885+ }
886+
887+ DocumentPointer (String absInitFolderPath ) {
888+ initializeDefaults ();
889+ fpInst .resetBaseDirectory ();
890+ isValid = fpInst .enterNextSubfolder (absInitFolderPath );
891+ this .absFolderPathOffset = absInitFolderPath ;
892+ }
893+
894+ public boolean isValid () { return isValid ; }
895+
896+ public boolean locateDocument (String documentPath ) throws FileNotFoundException {
897+ if (!isValid ()) {
898+ return false ;
899+ }
900+ this .filePath = documentPath .replaceFirst (fpInst .getCWD (), "" );
901+ File docFile = new File (fpInst .getCWD (), filePath );
902+ documentId = fpInst .getDocIdForFile (docFile );
903+ return true ;
904+ }
905+
906+ public boolean deleteDocument () throws FileNotFoundException {
907+ if (!isValid () || documentId == null ) {
908+ return false ;
909+ }
910+ fpInst .deleteDocument (documentId );
911+ return true ;
912+ }
913+
914+ public String getDocumentType () throws FileNotFoundException {
915+ if (!isValid () || documentId == null ) {
916+ return null ;
917+ }
918+ return fpInst .getDocumentType (documentId );
919+ }
920+
921+ public long getDocumentSize () throws FileNotFoundException {
922+ if (!isValid () || documentId == null ) {
923+ return 0 ;
924+ }
925+ return fpInst .getDocumentSize (documentId );
926+ }
927+
928+ public StringBuilder readFileContentsAsString (int offset , int maxBytes ) {
929+ if (!isValid () || documentId == null ) {
930+ return null ;
931+ }
932+ return fpInst .readFileContentsAsString (documentId , offset , maxBytes );
933+ }
934+
935+ public byte [] readFileContentsAsByteArray (int offset , int maxBytes ) {
936+ if (!isValid () || documentId == null ) {
937+ return null ;
938+ }
939+ return fpInst .readFileContentsAsByteArray (documentId , offset , maxBytes );
940+ }
941+
942+ }
943+
826944}
0 commit comments