In this article, I would like to talk about files on mobile devices. We'll create files, open them in a file explorer, and filter by type. Let's go.
Above all, let's create a simple MAUI project:
dotnet new maui -n FilePickAndSaveSample
Let's go to the "MainPage.xaml” file and delete all elements in VerticalStackLayout block. It's no need us. In "MainePage.xaml.cs” file, the same delete redutant code and leave only constructor.
Following step, you need to install the "CommunityToolkit.Maui” package. After you'll do it, you should register it. For this go to the "MauiProgram.cs” and add this code:
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
Next, let's make saving files to our mobile device. Lets back to our "MainPage.xaml” file and add a couple items: button and label.
<Label
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
LineBreakMode="WordWrap"
Text="The FileSaver provides the ability to select target folder and save files to the file system." />
<Button
Clicked="SaveFile_Clicked"
HorizontalOptions="Center"
Text="Save file" />
And then go to the "MainPage.xaml.cs” file and create two handlers:
private async void SaveFile_Clicked(object sender, EventArgs e)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
try
{
await SaveFile(cancellationToken);
}
catch (OperationCanceledException)
{
throw new OperationCanceledException("It was cancelled");
}
}
And also let's create a separate method for save files:
private async Task SaveFile(CancellationToken cancellationToken)
{
using var stream = new MemoryStream(Encoding.Default.GetBytes("Hello from the Dev.to Community!"));
var fileName = Application.Current?.MainPage?.DisplayPromptAsync("FileSaver", "Choose filename") ?? Task.FromResult("untitled.txt");
var fileSaverResult = await FileSaver.Default.SaveAsync(await fileName, stream, cancellationToken);
if (fileSaverResult.IsSuccessful)
{
await Toast.Make($"The file was saved successfully to location: {fileSaverResult.FilePath}").Show(cancellationToken);
}
else
{
await Toast.Make($"The file was not saved successfully with error: {fileSaverResult.Exception.Message}").Show(cancellationToken);
}
}
But it's not all. Let's go back to the "MauiProgram.cs” file and register service, just add this row:
builder.Services.AddSingleton(FileSaver.Default);
By the way. How you might have noticed we injected service FileSaver statical way, but you can use another two ways: inject to constructor or create new instance. For convenient, I'll use static injecting.
But anyway let's check out.
Click to the "Save TXT” button:
Type "plain_text.txt” and tap OK. Further, choose local storage and move into it. Repeat the same procedure for “doc_text.doc” and "pic.jpeg”
And now, lets create service for pick folder. It's everything similiar with save file. First, go to the "MauiProgram.cs” file and register new service:
builder.Services.AddSingleton(FolderPicker.Default);
And also add lable and button:
<Label
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
LineBreakMode="WordWrap"
Text="FolderPicker allows you to pick a folder from the device" />
<Button
Clicked="PickFolder_Clicked"
HorizontalOptions="Center"
Text="Pick Folder" />
Also it needs handler and method:
private async void PickFolder_Clicked(object sender, EventArgs e)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
try
{
await PickFolder(cancellationToken);
}
catch (OperationCanceledException)
{
throw new OperationCanceledException("It was cancelled");
}
}
private async Task PickFolder(CancellationToken cancellationToken)
{
var folderResult = await FolderPicker.PickAsync("DCIM", cancellationToken);
if (folderResult.IsSuccessful)
{
var filesCount = Directory.EnumerateFiles(folderResult.Folder.Path).Count();
await Toast.Make($"Folder picked: Name - {folderResult.Folder.Name}, Path - {folderResult.Folder.Path}, Files count - {filesCount}", ToastDuration.Long).Show(cancellationToken);
}
else
{
await Toast.Make($"Folder is not picked, {folderResult.Exception.Message}").Show(cancellationToken);
}
}
Lets check out:
Click on the "Pick Folder” and select folder. If tap to button again, you'll be at the same folder that you selected earlier.
And last thing that I wanted to show, it's pick file by type. Lets to do it and register service:
builder.Services.AddSingleton(FilePicker.Default);
Add the lable and the couple of buttons:
<Label
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
LineBreakMode="WordWrap"
Text="FilePicker allows you to pick a file from the device" />
<Button
Clicked="PickPhoto_Clicked"
HorizontalOptions="Center"
Text="Pick a Photo" />
<Button
Clicked="PickFile_Clicked"
HorizontalOptions="Center"
Text="Pick a File" />
<Label
FontSize="15"
HorizontalTextAlignment="Center"
x:Name="FileName" />
Add handlers:
private async void PickPhoto_Clicked(object sender, EventArgs e)
{
FileResult result = await _filePicker.PickAsync(new PickOptions
{
PickerTitle = "Pick a Photo",
FileTypes = FilePickerFileType.Images
});
if (result == null) return;
FileName.Text = result.FileName;
}
private async void PickFile_Clicked(object sender, EventArgs e)
{
var customFileTypes = new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
{
{
DevicePlatform.iOS, new[]
{
"com.microsoft.word.doc",
"public.plain-text",
"org.openxmlformats.wordprocessingml.document"
}
},
{
DevicePlatform.Android, new[]
{
"application/msword",
"text-plain",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
},
{
DevicePlatform.WinUI, new[]
{
"doc","docx", "txt"
}
},
});
FileResult result = await _filePicker.PickAsync(new PickOptions
{
PickerTitle = "Pick a File",
FileTypes = customFileTypes
});
if (result == null) return;
FileName.Text = result.FileName;
}
And now we can check out. If you click "Pick a Photo”, you can choose only pictures.
Thats all. Source: CLICK
Happy coding!