@@ -29,11 +29,20 @@ public class SAFFileWriter {
2929 private DocumentFile appDirectory ;
3030 private DocumentFile externalCacheDirectory ;
3131 private DocumentFile externalParentFile ;
32+ private final SharedPreferences preferences ;
3233 private int requestCode ;
3334 private static final String canNotCreateDirectory = "Can not create directory: " ;
3435 private static final String canNotWriteFile = "Can not write file: " ;
3536
3637
38+ /**
39+ * Inits new SAFFileWriter object, it will first check whether we already have a parent directory with proper uri access or not.
40+ *
41+ * @param activity:
42+ * Activity for context and starting request for OPEN_DOCUMENT_TREE
43+ * @param requestCode:
44+ * Request code to listen to OPEN_DOCUMENT_TREE
45+ */
3746 public SAFFileWriter (Activity activity , int requestCode ) {
3847 this .activity = activity ;
3948 this .requestCode = requestCode ;
@@ -48,52 +57,105 @@ public SAFFileWriter(Activity activity, int requestCode) {
4857 } else {
4958 externalCacheDirectory = DocumentFile .fromFile (dirs [0 ]);
5059 }
51- SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences (activity );
60+ preferences = PreferenceManager .getDefaultSharedPreferences (activity );
5261 String externalDirUrl = preferences .getString (PARENT_URI_KEY , "" );
5362 if (ConstantMethods .isEmptyString (externalDirUrl )) {
5463 Intent intent = new Intent (Intent .ACTION_OPEN_DOCUMENT_TREE );
5564 activity .startActivityForResult (intent , requestCode );
5665 }
5766 }
5867
68+ /**
69+ * Creates subdirectory in parent directory
70+ *
71+ * @param parentDirectory
72+ * : Parent directory where directory with "directoryName" should be created
73+ * @param displayName
74+ * name of subdirectory
75+ *
76+ * @return File object of created subdirectory
77+ *
78+ * @throws ExternalFileWriterException
79+ * if external storage is not available
80+ */
5981 public DocumentFile createSubDirectory (String displayName , DocumentFile parentDirectory ) {
60- return parentDirectory . createDirectory ( displayName );
61- }
82+ getAppDirectory ( );
83+ if ( isDirectoryExists ( displayName , parentDirectory )) {
6284
63- public DocumentFile createSubdirectory (String directoryName , boolean inCache ) {
64- DocumentFile appDirectory = getAppDirectory (inCache );
65- return appDirectory .createDirectory (directoryName );
85+ return parentDirectory .createDirectory (displayName );
86+ } else {
87+ return parentDirectory .findFile (displayName );
88+ }
6689 }
6790
91+ /**
92+ * Get created app directory
93+ *
94+ * @return File object of created AppDirectory
95+ */
6896 public DocumentFile getAppDirectory () {
6997 if (appDirectory == null ) {
7098 createAppDirectory ();
7199 }
72100 return appDirectory ;
73101 }
74102
103+ /**
104+ * Check whether directory with given name exists in parentDirectory or not.
105+ *
106+ * @param directoryName
107+ * : Name of the directory to check.
108+ * @param parentDirectory
109+ * : Parent directory where directory with "directoryName" should be present
110+ *
111+ * @return true if a directory with "directoryName" exists, false otherwise
112+ */
113+ public boolean isDirectoryExists (String displayName , DocumentFile parentDirectory ) {
114+ DocumentFile file = parentDirectory .findFile (displayName );
115+ return file != null && file .isDirectory ();
116+ }
117+
118+ /** Creates app directory */
75119 private void createAppDirectory () {
76120 String directoryName = activity .getString (activity .getApplicationInfo ().labelRes );
77121 appDirectory = externalParentFile .createDirectory (directoryName );
78122 appCacheDirectory = externalCacheDirectory .createDirectory (directoryName );
79123 }
80124
81- public void handleResult (int requestCode , int resultCode , Intent data ) {
82- if (resultCode == Activity .RESULT_OK ) {
83- if (requestCode == this .requestCode ) {
84- Uri treeUri = data .getData ();
85- externalParentFile = DocumentFile .fromTreeUri (activity , treeUri );
86-
125+ /**
126+ * Creates subdirectory in application directory
127+ *
128+ * @param directoryName
129+ * name of subdirectory
130+ *
131+ * @return File object of created subdirectory
132+ *
133+ * @throws ExternalFileWriterException
134+ * if external storage is not available
135+ */
136+ public DocumentFile createSubdirectory (String directoryName , boolean inCache ) {
137+ getAppDirectory ();
138+ DocumentFile appDirectory = getAppDirectory (inCache );
139+ if (!isDirectoryExists (directoryName , inCache )) {
87140
88- }
141+ return appDirectory .createDirectory (directoryName );
142+ } else {
143+ return appDirectory .findFile (directoryName );
89144 }
90145 }
91146
92- public boolean isDirectoryExists (String displayName , DocumentFile parentDirectory ) {
93- DocumentFile file = parentDirectory .findFile (displayName );
94- return file != null && file .isDirectory ();
147+ public DocumentFile getAppDirectory (boolean inCache ) {
148+ return (inCache ) ? this .appCacheDirectory : this .appDirectory ;
95149 }
96150
151+ /**
152+ * Checks whether directory with given name exists in AppDirectory
153+ *
154+ * @param directoryName
155+ * : Name of the directory to check.
156+ *
157+ * @return true if a directory with "directoryName" exists, false otherwise
158+ */
97159 public boolean isDirectoryExists (String displayName , boolean inCache ) {
98160 DocumentFile file = getDocumentFile (displayName , inCache );
99161 return file != null && file .isDirectory ();
@@ -104,26 +166,72 @@ private DocumentFile getDocumentFile(String displayName, boolean inCache) {
104166 return appDirectory .findFile (displayName );
105167 }
106168
107- public boolean isFileExists (String displayName , boolean inCache ) {
108- DocumentFile file = getDocumentFile (displayName , inCache );
109- return file != null && file .isFile ();
169+ public void handleResult (int requestCode , int resultCode , Intent data ) {
170+ if (resultCode == Activity .RESULT_OK ) {
171+ if (requestCode == this .requestCode ) {
172+ Uri treeUri = data .getData ();
173+ externalParentFile = DocumentFile .fromTreeUri (activity , treeUri );
174+ preferences .edit ().putString (PARENT_URI_KEY , String .valueOf (externalParentFile .getUri ()));
175+ getAppDirectory ();
176+
177+ }
178+ }
110179 }
111180
112- public boolean isFileExists (String displayName , DocumentFile parentDirectory ) {
113- DocumentFile file = parentDirectory .findFile (displayName );
181+ /**
182+ * Check whether file with given name exists in parentDirectory or not.
183+ *
184+ * @param fileName
185+ * : Name of the file to check.
186+ * @param parentDirectory
187+ * : Parent directory where directory with "fileName" should be present
188+ *
189+ * @return true if a file with "fileName" exists, false otherwise
190+ */
191+ public boolean isFileExists (String displayName , boolean inCache ) {
192+ DocumentFile file = getDocumentFile (displayName , inCache );
114193 return file != null && file .isFile ();
115194 }
116195
117196 public void writeDataToFile (String fileName , String mimeType , byte [] data , boolean inCache ) throws FileNotFoundException {
197+ getAppDirectory ();
118198 DocumentFile appDir = getAppDirectory (inCache );
119199 writeDataToFile (appDir , fileName , data , mimeType );
120200 }
121201
202+ /**
203+ * Writes data to the file. The file will be created in the directory name same as app.
204+ *
205+ * @param fileName
206+ * name of the file
207+ * @param data
208+ * data to write
209+ *
210+ * @throws ExternalFileWriterException
211+ * if external storage is not available or free space is less than size of the data
212+ */
122213 public void writeDataToFile (DocumentFile parent , String fileName , byte [] data , String mimeType ) throws FileNotFoundException {
123214 DocumentFile file = createFile (fileName , parent , mimeType );
124215 writeDataToFile (file , data );
125216 }
126217
218+ private DocumentFile createFile (String fileName , DocumentFile parent , String mimeType ) {
219+ if (!isFileExists (fileName , parent )) {
220+
221+ return parent .createFile (mimeType , fileName );
222+ } else {
223+ return parent .findFile (fileName );
224+ }
225+ }
226+
227+ /**
228+ * Write byte array to file. Will show error if given file is a directory.
229+ *
230+ * @param file
231+ * : File where data is to be written.
232+ * @param data
233+ * byte array which you want to write a file. If size of this is greater than size available, it will show error.
234+ */
127235 private void writeDataToFile (DocumentFile file , byte [] data ) throws FileNotFoundException {
128236 ParcelFileDescriptor fileDescriptor = activity .getContentResolver ().openFileDescriptor (file .getUri (), "w" );
129237 FileOutputStream out = null ;
@@ -138,11 +246,37 @@ private void writeDataToFile(DocumentFile file, byte[] data) throws FileNotFound
138246 }
139247 }
140248
249+ /**
250+ * Checks whether file with given name exists in AppDirectory
251+ *
252+ * @param fileName
253+ * : Name of the file to check.
254+ *
255+ * @return true if a file with "directoryName" exists, false otherwise
256+ */
257+ public boolean isFileExists (String displayName , DocumentFile parentDirectory ) {
258+ DocumentFile file = parentDirectory .findFile (displayName );
259+ return file != null && file .isFile ();
260+ }
261+
141262 public void writeDataToFile (String fileName , String mimeType , String data , boolean inCache ) throws FileNotFoundException {
142263 DocumentFile appDir = getAppDirectory (inCache );
143264 writeDataToFile (appDir , fileName , data , mimeType );
144265 }
145266
267+ /**
268+ * Write data in file of a parent directory
269+ *
270+ * @param parent
271+ * parent directory
272+ * @param fileName
273+ * desired filename
274+ * @param data
275+ * data
276+ *
277+ * @throws ExternalFileWriterException
278+ * if external storage is not available or free space is less than size of the data
279+ */
146280 public void writeDataToFile (DocumentFile parent , String fileName , String data , String mimeType ) throws FileNotFoundException {
147281 DocumentFile file = createFile (fileName , parent , mimeType );
148282 writeDataToFile (file , data );
@@ -193,12 +327,4 @@ private DocumentFile createFile(String fileName, boolean inCache, String mimeTyp
193327 return createFile (fileName , getAppDirectory (inCache ), mimeType );
194328 }
195329
196- private DocumentFile createFile (String fileName , DocumentFile parent , String mimeType ) {
197- return parent .createFile (mimeType , fileName );
198- }
199-
200- public DocumentFile getAppDirectory (boolean inCache ) {
201- return (inCache ) ? this .appCacheDirectory : this .appDirectory ;
202- }
203-
204330}
0 commit comments