mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-15 00:05:45 -04:00
Android: Allow opening/getting files relative to downloads directory
This commit is contained in:
@ -20,6 +20,7 @@ import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* File helper class - used to bridge native code to Java storage access framework APIs.
|
||||
@ -53,6 +54,21 @@ public class FileHelper {
|
||||
DocumentsContract.Document.COLUMN_LAST_MODIFIED
|
||||
};
|
||||
|
||||
/**
|
||||
* Projection used when getting the display name for a file.
|
||||
*/
|
||||
private static final String[] getDisplayNameProjection = new String[]{
|
||||
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
|
||||
};
|
||||
|
||||
/**
|
||||
* Projection used when getting a relative file for a file.
|
||||
*/
|
||||
private static final String[] getRelativeFileProjection = new String[]{
|
||||
DocumentsContract.Document.COLUMN_DOCUMENT_ID,
|
||||
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
|
||||
};
|
||||
|
||||
private final Context context;
|
||||
private final ContentResolver contentResolver;
|
||||
|
||||
@ -244,6 +260,7 @@ public class FileHelper {
|
||||
|
||||
/**
|
||||
* Returns the file name component of a path or URI.
|
||||
*
|
||||
* @param path Path/URI to examine.
|
||||
* @return File name component of path/URI.
|
||||
*/
|
||||
@ -265,6 +282,14 @@ public class FileHelper {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the given URI represents a {@link DocumentsContract.Document} tree.
|
||||
*/
|
||||
public static boolean isTreeUri(Uri uri) {
|
||||
final List<String> paths = uri.getPathSegments();
|
||||
return (paths.size() >= 2 && paths.get(0).equals("tree"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a file descriptor for a content URI string. Called by native code.
|
||||
*
|
||||
@ -353,6 +378,91 @@ public class FileHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display name for the given URI.
|
||||
*
|
||||
* @param uriString URI to resolve display name for.
|
||||
* @return display name for the URI, or null.
|
||||
*/
|
||||
public String getDisplayNameForURIPath(String uriString) {
|
||||
try {
|
||||
final Uri fullUri = Uri.parse(uriString);
|
||||
final Cursor cursor = contentResolver.query(fullUri, getDisplayNameProjection,
|
||||
null, null, null);
|
||||
if (cursor.getCount() == 0 || !cursor.moveToNext())
|
||||
return null;
|
||||
|
||||
return cursor.getString(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path for a sibling file relative to another URI.
|
||||
*
|
||||
* @param uriString URI to find the file relative to.
|
||||
* @param newFileName Sibling file name.
|
||||
* @return URI for the sibling file name, or null.
|
||||
*/
|
||||
public String getRelativePathForURIPath(String uriString, String newFileName) {
|
||||
try {
|
||||
final Uri fullUri = Uri.parse(uriString);
|
||||
|
||||
// if this is a document (expected)...
|
||||
Uri treeUri;
|
||||
String treeDocId;
|
||||
if (DocumentsContract.isDocumentUri(context, fullUri)) {
|
||||
// we need to remove the last part of the URI (the specific document ID) to get the parent
|
||||
final String lastPathSegment = fullUri.getLastPathSegment();
|
||||
int lastSeparatorIndex = lastPathSegment.lastIndexOf('/');
|
||||
if (lastSeparatorIndex < 0)
|
||||
lastSeparatorIndex = lastPathSegment.lastIndexOf(':');
|
||||
if (lastSeparatorIndex < 0)
|
||||
return null;
|
||||
|
||||
// the parent becomes the document ID
|
||||
treeDocId = lastPathSegment.substring(0, lastSeparatorIndex);
|
||||
|
||||
// but, we need to access it through the subtree if this was a tree URI (permissions...)
|
||||
if (isTreeUri(fullUri)) {
|
||||
treeUri = DocumentsContract.buildTreeDocumentUri(fullUri.getAuthority(), DocumentsContract.getTreeDocumentId(fullUri));
|
||||
} else {
|
||||
treeUri = DocumentsContract.buildTreeDocumentUri(fullUri.getAuthority(), treeDocId);
|
||||
}
|
||||
} else {
|
||||
treeDocId = DocumentsContract.getDocumentId(fullUri);
|
||||
treeUri = fullUri;
|
||||
}
|
||||
|
||||
final Uri queryUri = DocumentsContract.buildChildDocumentsUriUsingTree(treeUri, treeDocId);
|
||||
final Cursor cursor = contentResolver.query(queryUri, getRelativeFileProjection, null, null, null);
|
||||
final int count = cursor.getCount();
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
final String displayName = cursor.getString(1);
|
||||
if (!displayName.equalsIgnoreCase(newFileName))
|
||||
continue;
|
||||
|
||||
final String childDocumentId = cursor.getString(0);
|
||||
final Uri uri = DocumentsContract.buildDocumentUriUsingTree(treeUri, childDocumentId);
|
||||
cursor.close();
|
||||
return uri.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Java class containing the data for a file in a find operation.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user