0

I am trying to build my own Music Player android app.

I want it to be very simple, just find all valid music files (perhaps I set file types such as mp3, m4a, wma etc for it to look for?) and play them in order of how they are found.

So far I have it so that I can find the default music folder path using

string musicDirectoryPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMusic).ToString();

What I now need is to check every file (and folder) inside that folder to see if it is mp3/m4a etc and then add them to the list. I've been messing and trying some foreach loops but cannot get anything useful.

I am very confused and quite new to Android development.

As you will see, if I specify a song that I know is on my phone in the default directory (*/NewPipe/Intergalatic - Beastie.m4a), then the music is playing.

So, how can I get a List of all those strings such as the "NewPipe/Beastie.." etc (along with the other 500+ folders inside my default music directory?

Here is my entire class so far (it's the only class in the project):

using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using Android.Media;
using Xamarin.Android;
using System.IO;
using System.Collections.Generic;
using Android.Util;

namespace Music_Player_v001
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
    protected MediaPlayer mediaPlayer;
    List<string> filepaths_audio = new List<string>();

    public void StartMediaPlayer(String filePath)
    {
        mediaPlayer.Reset();
        mediaPlayer.SetDataSource(filePath);
        mediaPlayer.Prepare();
        mediaPlayer.Start();
    }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);

        FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
        fab.Click += FabOnClick;

        string musicDirectoryPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMusic).ToString();
        Log.Info("FILEPATHS: ", "music directory path is: " + musicDirectoryPath);

        mediaPlayer = new MediaPlayer();
        StartMediaPlayer(musicDirectoryPath + "/NewPipe/Intergalactic - Beastie Boys (HD).m4a");

        //foreach(AudioTrack track in Android.OS.Environment.DirectoryMusic)
        //{
        //    Log.Info("BULLSHIT TAG","track count =======================" + tracks);
        //    tracks++;

        //}
    }

    public override bool OnCreateOptionsMenu(IMenu menu)
    {
        MenuInflater.Inflate(Resource.Menu.menu_main, menu);
        return true;
    }

    public override bool OnOptionsItemSelected(IMenuItem item)
    {
        int id = item.ItemId;
        if (id == Resource.Id.action_settings)
        {
            return true;
        }

        return base.OnOptionsItemSelected(item);
    }

    private void FabOnClick(object sender, EventArgs eventArgs)
    {
        View view = (View) sender;
        Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
            .SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
    }


}
}

Additional

I also tried this:

 foreach (File f in Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMusic))
        {


        }
halfer
  • 19,824
  • 17
  • 99
  • 186
Big T Larrity
  • 221
  • 2
  • 9

1 Answers1

1

It sounds like your main issue is recursively iterating through all the files in the directory and its subdirectories. Here are a few relevant links:

How to recursively list all the files in a directory in C#?

Best way to iterate folders and subfolders

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-iterate-through-a-directory-tree

The easiest approach is probably Directory.EnumerateFiles, used like this: Directory.EnumerateFiles(musicDirectoryPath, "*", SearchOption.AllDirectories) to ensure that it also enumerates through the sub-directories.

foreach (string musicFilePath in Directory.EnumerateFiles(musicDirectoryPath, "*", SearchOption.AllDirectories)) {
        Log.Info("Music File", "Music file path is " + musicFilePath);
        // do whatever you want to with the file here
}

Note that this may fail if there is an access-restricted directory (or some other error) somewhere in the tree. If you'd like your solution to work around this, see the links I posted above, particularly the bottom one.

Also note, you can change that "*" (wildcard) in the method call to "*.mp3" or "*.wav" or so on, to only match files with those extensions. However, as the method doesn't support regex, I don't think there's any way to match multiple file extensions (like BOTH mp3 and wav). I think you'd have to use the "*" and then just check within the foreach if the file is a valid music file.

nbura
  • 368
  • 3
  • 15
  • 1
    Wow this looks great! thanks mate. I will try give this a go before I get to sleep (long overdue sleep been at this for so many hours but couldnt stop trying to solve it haha). I'll come back to confirm it all works soon. Thanks again! – Big T Larrity Jun 17 '19 at 03:40
  • you sir are an absolute legend! – Big T Larrity Jun 17 '19 at 03:59
  • 1
    No problem, glad it worked :) Just be sure you're aware that this may fail if there's access restricted stuff in the music directory. If it's a hobby project I'm sure it'll be fine... but probably not a good idea to do this in a production app! – nbura Jun 17 '19 at 04:02
  • it actually fails still :[ but now the error is: Exception Unhandled at line 'mediaPlayer.SetDataSource(filepath); – Big T Larrity Jun 17 '19 at 04:03
  • Unhandled Exception: Java.IO.FileNotFoundException: /storage/emulated/0/Music: open failed: EISDIR (Is a directory) occurred – Big T Larrity Jun 17 '19 at 04:05
  • hmm i have set the External Read and Write permissions to on, but no change. still much appreciate your answer and Im sure it is correct. Maybe fresh eyes tomorrow I can get it to work. Cheers again all – Big T Larrity Jun 17 '19 at 04:08
  • Huh, it sounds like `EnumerateFiles()` may also be enumerating the directories? That's weird. Maybe add a check before calling `StartMediaPlayer()`, and use a combination of stuff like `Path.GetExtension` and `File.Exists` to ensure that `musicFilePath` is indeed a valid music file, and is not a directory. – nbura Jun 17 '19 at 04:17
  • 1
    well in logcat i actually see the names of the songs!!! but then it failed... OH I just fixed it haha, i am idiot, i was giving it filename + filepaths[0], but the latter already included the former, also i had to change the wildcard to just m4a, so i guess it was finding a file that wasnt supported (eg jpg or something) – Big T Larrity Jun 17 '19 at 04:19