Reputation: 3794
I am currently trying to retrieve music files within a specific folder from the ContentResolver. I only want the files in that folder, not from a subfolder. I achieved to get these files by doing this:
String pattern = f.getAbsolutePath() + "/[^/]*"; // f is the folder where I want to search
ArrayList<TrackInfo> retVal = new ArrayList<TrackInfo>();
Cursor mCursor = null;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0 AND " + DATA + " LIKE '" + f.getAbsolutePath() + "/%'";
Uri contentUri = Media.getContentUriForPath(Environment.getExternalStorageDirectory().getPath());
String projection[] = new String[]{DATA};
mCursor = context.getContentResolver().query(contentUri, projection, selection, null, DATA);
String data, fileName[];
while(mCursor.moveToNext()){
data = mCursor.getString(0);
if(data.matches(pattern)){
fileName = data.split("/");
retVal.add(new TrackInfo(fileName[fileName.length-1], null, data, null, -1, R.drawable.notes, false));
}
}
mCursor.close();
This worked out for most cases. But now I seem to have an issue with my pattern. The problem is that if the pattern contains parentheses, data.matches(pattern)
always returns false. Examples I tried were:
String pattern1 = "/mnt/somepath/folder(with-parentheses)/[^/]*";
String pattern2 = "/mnt/somepath/folder/[^/]*";
String string1 = "/mnt/somepath/folder(with-parentheses)/test1";
String string2 = "/mnt/somepath/folder/test2";
System.out.println("\"" + string1 + "\"" + ".matches(\"" + pattern1 + "\") = " + string1.matches(pattern1));
System.out.println("\"" + string2 + "\".matches(\"" + pattern2 + "\") = " + string2.matches(pattern2));
The output was:
"/mnt/somepath/folder(with-parentheses)/test1*".matches("/mnt/somepath/folder(with-parentheses)/[^/]*") = false
"/mnt/somepath/folder/test2".matches("/mnt/somepath/folder/[^/]*") = true
My question now is:
Is there a more effective way to get all music files within a folder? - I have already tried to check every file within a folder for a pattern (containing the supported media formats I found here). The problem with that approach is that these formats are only Core Media Formats - the phone may support more than that.
And why is my pattern not working?
Thanks a lot.
Upvotes: 2
Views: 1437
Reputation: 56829
(
, )
(and many others such as +
,*
,[
,]
, .
) are special characters in regex. Therefore, it is necessary to escape them, i.e. \(
, \)
in order to specify the literal character.
However, in this case, since you obtain the pattern by concatenating f.getAbsolutePath()
, it is strongly recommended that you use Pattern.quote(String)
to make all characters in f.getAbsolutePath()
literal. It will make sure none of the character are interpreted as special character in regex.
String pattern = Pattern.quote(f.getAbsolutePath()) + "/[^/]*";
(When you print out the pattern
after applying Pattern.quote
, you may notice that it adds \Q
and \E
to the original string. It is the way to escape all characters in a long string, supported by Java regex and several other regex flavors).
Upvotes: 2