Home > Software design >  How do I get data about all audio files in the user's device using Xamarin (Android)?
How do I get data about all audio files in the user's device using Xamarin (Android)?

Time:10-11

I'm creating a music player app, and I want to be able to automatically scan the user's device for audio files when launched, then create databases of songs, albums, and artists (which can then be displayed and played when clicked).

So far, I've looked at a few guides and similar questions, and based on those, I've come up with this code:

string[] columns = {
    MediaStore.Audio.Media.InterfaceConsts.IsMusic,
    MediaStore.Audio.Media.InterfaceConsts.RelativePath,
    MediaStore.Audio.Media.InterfaceConsts.Title,
};
ICursor cursor = context?.ContentResolver?.Query(MediaStore.Audio.Media.ExternalContentUri, columns, null, null, null);
if (cursor is null)
{
    return;
}
while (cursor.MoveToNext())
{
    if (!Boolean.Parse(cursor.GetString(0)))
    {
        continue;
    }

    string trackPath = cursor.GetString(1);
    string trackTitle = cursor.GetString(2);
}
cursor.Close();

The idea here is to just query the data I need (song file paths, titles, albums, artists, etc) and store them as my own data structures for better readability (and to access them from my classes that handle UI).

However, it doesn't seem to work, and I can't understand why. For reference, I'm testing it out on the Xamarin Android emulator (API version 29), and I've got a few .mp3 files in the "Downloads" folder of the virtual device.

From some logging, I've figured out that cursor is not null, but it doesn't contain any data to iterate over. The app has all the permissions it needs (read/write external storage, access media location, etc), so it should be able to read files. That leaves MediaStore.Audio.Media.ExternalContentUri as a potential culprit, but I don't know of any other way to get the URI for files stored on the device.

What am I doing wrong? Any help would be appreciated. Thanks.

CodePudding user response:

Fixed this problem. Turns out that even though InterfaceConsts.Data is marked as obsolete, it still works as expected and will give you the absolute path to the media file. So using the same code as in the question:

string[] columns = {
    MediaStore.Audio.Media.InterfaceConsts.IsMusic,
    MediaStore.Audio.Media.InterfaceConsts.Data,
    MediaStore.Audio.Media.InterfaceConsts.Title,
};
ICursor cursor = context?.ContentResolver?.Query(MediaStore.Audio.Media.ExternalContentUri, columns, null, null, null);
if (cursor is null)
{
    return;
}
while (cursor.MoveToNext())
{
    if (!Boolean.Parse(cursor.GetString(0)))
    {
        continue;
    }

    string trackPath = cursor.GetString(1);
    string trackTitle = cursor.GetString(2);
}
cursor.Close();

That should work.

  • Related