3030import android .provider .DocumentsContract .Document ;
3131
3232import java .io .Closeable ;
33+ import java .io .File ;
3334import java .io .FileNotFoundException ;
34- import java .nio .file .InvalidPathException ;
35- import java .nio .file .Path ;
36- import java .nio .file .Paths ;
35+ import java .io .IOException ;
3736
3837public final class VfsImplementationSaf
3938{
4039 private static final String [] QUERY_ARGS_MIME_TYPE = {
4140 Document .COLUMN_MIME_TYPE ,
4241 };
4342
43+ private static String normalizePath (String path ) {
44+ try
45+ {
46+ return new File ("/" + path ).getCanonicalPath ();
47+ }
48+ catch (IOException e )
49+ {
50+ return "/" ;
51+ }
52+ }
53+
54+ private static String getPathParent (String path ) {
55+ try
56+ {
57+ return new File ("/" + path ).getCanonicalFile ().getParent ();
58+ }
59+ catch (IOException e )
60+ {
61+ return null ;
62+ }
63+ }
64+
65+ private static String getPathFileName (String path ) {
66+ try
67+ {
68+ return new File ("/" + path ).getCanonicalFile ().getName ();
69+ }
70+ catch (IOException e )
71+ {
72+ return null ;
73+ }
74+ }
75+
4476 /**
4577 * Open a Storage Access Framework file, returning its file descriptor if successful or -1 if not.
4678 * The file is not guaranteed to be seeked to any particular position, so it may be a good idea to seek it immediately after opening.
@@ -55,21 +87,12 @@ public static int openSafFile(ContentResolver content, String tree, String path,
5587 {
5688 if (Build .VERSION .SDK_INT < 21 )
5789 return -1 ;
90+ path = normalizePath (path );
5891 boolean createdFile = false ;
5992 while (true )
6093 {
6194 final Uri treeUri = Uri .parse (tree );
62- final Path filePath ;
63- try
64- {
65- filePath = Paths .get ("/" + path ).normalize ();
66- }
67- catch (InvalidPathException e )
68- {
69- return -1 ;
70- }
71- final String filePathString = filePath .toString ();
72- final Uri fileUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , filePathString .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + filePathString );
95+ final Uri fileUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , path .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + path );
7396 final String mode ;
7497 if (!write )
7598 mode = "r" ;
@@ -96,14 +119,13 @@ else if (!read)
96119 if (createdFile || !write || !truncate )
97120 return -1 ;
98121 createdFile = true ;
99- final Path parentPath = filePath . getParent ( );
122+ final String parentPath = getPathParent ( path );
100123 if (parentPath == null )
101124 return -1 ;
102- final String parentPathString = parentPath .toString ();
103- final Uri parentUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , parentPathString .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + parentPathString );
125+ final Uri parentUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , parentPath .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + parentPath );
104126 try
105127 {
106- DocumentsContract .createDocument (content , parentUri , "application/octet-stream" , filePath . getFileName (). toString ( ));
128+ DocumentsContract .createDocument (content , parentUri , "application/octet-stream" , getPathFileName ( path ));
107129 }
108130 catch (FileNotFoundException | IllegalArgumentException f )
109131 {
@@ -124,14 +146,7 @@ public static boolean removeSafFile(ContentResolver content, String tree, String
124146 if (Build .VERSION .SDK_INT < 21 )
125147 return false ;
126148 final Uri treeUri = Uri .parse (tree );
127- try
128- {
129- path = Paths .get ("/" + path ).normalize ().toString ();
130- }
131- catch (InvalidPathException e )
132- {
133- return false ;
134- }
149+ path = normalizePath (path );
135150 path = path .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + path ;
136151 final Uri fileUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , path );
137152 try
@@ -172,14 +187,7 @@ public SafStat(ContentResolver content, String tree, String path, boolean includ
172187 if (Build .VERSION .SDK_INT < 21 )
173188 return ;
174189 final Uri treeUri = Uri .parse (tree );
175- try
176- {
177- path = Paths .get ("/" + path ).normalize ().toString ();
178- }
179- catch (InvalidPathException e )
180- {
181- return ;
182- }
190+ path = normalizePath (path );
183191 path = path .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + path ;
184192 final Uri fileUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , path );
185193 final Cursor cursor ;
@@ -244,15 +252,7 @@ public static int mkdirSaf(ContentResolver content, String tree, String path)
244252 if (Build .VERSION .SDK_INT < 21 )
245253 return -1 ;
246254 final Uri treeUri = Uri .parse (tree );
247- final Path directoryPath ;
248- try
249- {
250- directoryPath = Paths .get ("/" + path ).normalize ();
251- }
252- catch (InvalidPathException e )
253- {
254- return -1 ;
255- }
255+ path = normalizePath (path );
256256 path = path .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + path ;
257257 final Uri directoryUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , path );
258258 Cursor cursor = null ;
@@ -274,14 +274,13 @@ public static int mkdirSaf(ContentResolver content, String tree, String path)
274274 cursor .close ();
275275 }
276276 }
277- final Path parentPath = directoryPath . getParent ( );
277+ final String parentPath = getPathParent ( path );
278278 if (parentPath == null )
279279 return -1 ;
280- final String parentPathString = parentPath .toString ();
281- final Uri parentUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , parentPathString .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + parentPathString );
280+ final Uri parentUri = DocumentsContract .buildDocumentUriUsingTree (treeUri , parentPath .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + parentPath );
282281 try
283282 {
284- if (DocumentsContract .createDocument (content , parentUri , Document .MIME_TYPE_DIR , directoryPath . getFileName (). toString ( )) == null )
283+ if (DocumentsContract .createDocument (content , parentUri , Document .MIME_TYPE_DIR , getPathFileName ( path )) == null )
285284 return -1 ;
286285 }
287286 catch (FileNotFoundException | IllegalArgumentException e )
@@ -314,14 +313,7 @@ public SafDirectory(ContentResolver content, String tree, String path)
314313 if (Build .VERSION .SDK_INT < 21 )
315314 return ;
316315 final Uri treeUri = Uri .parse (tree );
317- try
318- {
319- path = Paths .get ("/" + path ).normalize ().toString ();
320- }
321- catch (InvalidPathException e )
322- {
323- return ;
324- }
316+ path = normalizePath (path );
325317 path = path .length () == 1 ? DocumentsContract .getTreeDocumentId (treeUri ) : DocumentsContract .getTreeDocumentId (treeUri ) + path ;
326318 prefixLength = path .length ();
327319 final Uri childrenUri = DocumentsContract .buildChildDocumentsUriUsingTree (treeUri , path );
0 commit comments