Skip to content

Commit 7445784

Browse files
committed
refactor: MediaFilePicker can be selected files in other ways on Android devices that support PhotoPicker
1 parent 2a6752c commit 7445784

File tree

4 files changed

+94
-17
lines changed

4 files changed

+94
-17
lines changed

src/MauiBlazorToolkit/MauiBlazorToolkit/Essentials/MediaFilePicker/MediaFilePicker.android.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
{
33
public partial class MediaFilePicker
44
{
5-
public static Task<IEnumerable<FileResult>?> PlatformPickMultiplePhotoAsync(bool usePhotoPicker = true)
5+
public static Task<IEnumerable<FileResult>?> PlatformPickMultiplePhotoAsync(bool usePhotoPicker = false)
66
=> MediaFilePickerImplementation.PlatformPickMultiplePhotoAsync(usePhotoPicker);
77

8-
public static Task<IEnumerable<FileResult>?> PlatformPickMultipleVideoAsync(bool usePhotoPicker = true)
8+
public static Task<IEnumerable<FileResult>?> PlatformPickMultipleVideoAsync(bool usePhotoPicker = false)
99
=> MediaFilePickerImplementation.PlatformPickMultipleVideoAsync(usePhotoPicker);
1010

11-
public static Task<FileResult?> PlatformPickPhotoAsync(bool usePhotoPicker = true)
11+
public static Task<FileResult?> PlatformPickPhotoAsync(bool usePhotoPicker = false)
1212
=> MediaFilePickerImplementation.PlatformPickPhotoAsync(usePhotoPicker);
1313

14-
public static Task<FileResult?> PlatformPickVideoAsync(bool usePhotoPicker = true)
14+
public static Task<FileResult?> PlatformPickVideoAsync(bool usePhotoPicker = false)
1515
=> MediaFilePickerImplementation.PlatformPickVideoAsync(usePhotoPicker);
1616

1717
}

src/MauiBlazorToolkit/MauiBlazorToolkit/Essentials/MediaFilePicker/MediaFilePickerImplementation.android.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ namespace MauiBlazorToolkit.Essentials
1212
[SupportedOSPlatform("Android")]
1313
internal sealed partial class MediaFilePickerImplementation
1414
{
15-
public static Task<IEnumerable<FileResult>?> PlatformPickMultiplePhotoAsync(bool usePhotoPicker = true)
15+
public static Task<IEnumerable<FileResult>?> PlatformPickMultiplePhotoAsync(bool usePhotoPicker = false)
1616
=> PlatformPickMultipleAsync(true, usePhotoPicker);
1717

18-
public static Task<IEnumerable<FileResult>?> PlatformPickMultipleVideoAsync(bool usePhotoPicker = true)
18+
public static Task<IEnumerable<FileResult>?> PlatformPickMultipleVideoAsync(bool usePhotoPicker = false)
1919
=> PlatformPickMultipleAsync(false, usePhotoPicker);
2020

21-
public static Task<FileResult?> PlatformPickPhotoAsync(bool usePhotoPicker = true)
21+
public static Task<FileResult?> PlatformPickPhotoAsync(bool usePhotoPicker = false)
2222
=> PlatformPickAsync(true, usePhotoPicker);
2323

24-
public static Task<FileResult?> PlatformPickVideoAsync(bool usePhotoPicker = true)
24+
public static Task<FileResult?> PlatformPickVideoAsync(bool usePhotoPicker = false)
2525
=> PlatformPickAsync(false, usePhotoPicker);
2626

2727
private static PickVisualMediaRequest BuilderPickVisualMediaRequest(bool photo)
@@ -31,7 +31,7 @@ private static PickVisualMediaRequest BuilderPickVisualMediaRequest(bool photo)
3131
.Build();
3232
}
3333

34-
private static async Task<FileResult?> PlatformPickAsync(bool photo, bool usePhotoPicker = true)
34+
private static async Task<FileResult?> PlatformPickAsync(bool photo, bool usePhotoPicker = false)
3535
{
3636
if (usePhotoPicker && IsPhotoPickerAvailable())
3737
{
@@ -49,7 +49,7 @@ private static PickVisualMediaRequest BuilderPickVisualMediaRequest(bool photo)
4949
}
5050
}
5151

52-
private static async Task<IEnumerable<FileResult>?> PlatformPickMultipleAsync(bool photo, bool usePhotoPicker = true)
52+
private static async Task<IEnumerable<FileResult>?> PlatformPickMultipleAsync(bool photo, bool usePhotoPicker = false)
5353
{
5454
if (usePhotoPicker && IsPhotoPickerAvailable())
5555
{

src/MauiBlazorToolkit/MauiBlazorToolkit/Extensions/AppBuilderExtensions/AppBuilderExtensions.shared.cs

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#endif
66
#if ANDROID
77
using static AndroidX.Activity.Result.Contract.ActivityResultContracts;
8+
using Android.App;
9+
using Android.Content;
810
#endif
911

1012
namespace MauiBlazorToolkit.Extensions
@@ -54,6 +56,10 @@ public static MauiAppBuilder UseMauiBlazorToolkit(this MauiAppBuilder builder, A
5456
PickMultipleVisualMediaForResult.Default.Register(componentActivity);
5557
}
5658
});
59+
android.OnActivityResult((Activity activity, int requestCode, Result resultCode, Intent? data) =>
60+
{
61+
MauiBlazorToolkit.Platform.IntermediateActivity.OnActivityResult(requestCode, resultCode, data);
62+
});
5763
});
5864
#endif
5965
});
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,88 @@
1-
using Android.Content;
2-
using System.Reflection;
1+
using Android.App;
2+
using Android.Content;
3+
using System.Collections.Concurrent;
34

4-
#nullable disable
55
namespace MauiBlazorToolkit.Platform
66
{
77
public class IntermediateActivity
88
{
9-
static readonly Type intermediateActivityType = typeof(FileSystem).Assembly.GetType("Microsoft.Maui.ApplicationModel.IntermediateActivity") ?? throw new Exception("IntermediateActivity type not found.");
10-
static readonly MethodInfo startAsync = intermediateActivityType.GetMethod("StartAsync", BindingFlags.Public | BindingFlags.Static) ?? throw new Exception("StartAsync method not found.");
9+
static readonly string guidExtra = Guid.NewGuid().ToString();
1110

12-
public static Task<Intent> StartAsync(Intent intent, int requestCode, Action<Intent>? onCreate = null, Action<Intent>? onResult = null)
11+
static readonly ConcurrentDictionary<string, IntermediateTask> pendingTasks = new();
12+
13+
static Activity? Activity => Microsoft.Maui.ApplicationModel.Platform.CurrentActivity;
14+
15+
internal static void OnActivityResult(int requestCode, Result resultCode, Intent? data)
16+
{
17+
string? guid = Activity?.Intent?.GetStringExtra(guidExtra);
18+
var task = GetIntermediateTask(guid, true);
19+
20+
if (task is null)
21+
return;
22+
23+
if (resultCode == Result.Canceled)
24+
{
25+
task.TaskCompletionSource.TrySetCanceled();
26+
}
27+
else
28+
{
29+
try
30+
{
31+
data ??= new Intent();
32+
33+
task.OnResult?.Invoke(data);
34+
35+
task.TaskCompletionSource.TrySetResult(data);
36+
}
37+
catch (Exception ex)
38+
{
39+
task.TaskCompletionSource.TrySetException(ex);
40+
}
41+
}
42+
}
43+
44+
public static Task<Intent> StartAsync(Intent intent, int requestCode, Action<Intent>? onResult = null)
45+
{
46+
var data = new IntermediateTask(onResult);
47+
pendingTasks[data.Id] = data;
48+
49+
Activity?.Intent?.PutExtra(guidExtra, data.Id);
50+
51+
Activity?.StartActivityForResult(intent, requestCode);
52+
53+
return data.TaskCompletionSource.Task;
54+
}
55+
56+
static IntermediateTask? GetIntermediateTask(string? guid, bool remove = false)
57+
{
58+
if (string.IsNullOrEmpty(guid))
59+
return null;
60+
61+
if (remove)
62+
{
63+
pendingTasks.TryRemove(guid, out var removedTask);
64+
return removedTask;
65+
}
66+
67+
pendingTasks.TryGetValue(guid, out var task);
68+
return task;
69+
}
70+
71+
class IntermediateTask
1372
{
14-
return startAsync.Invoke(null, [intent, requestCode, onCreate, onResult]) as Task<Intent>;
73+
public IntermediateTask(Action<Intent>? onResult)
74+
{
75+
Id = Guid.NewGuid().ToString();
76+
TaskCompletionSource = new TaskCompletionSource<Intent>();
77+
78+
OnResult = onResult;
79+
}
80+
81+
public string Id { get; }
82+
83+
public TaskCompletionSource<Intent> TaskCompletionSource { get; }
84+
85+
public Action<Intent>? OnResult { get; }
1586
}
1687
}
1788
}

0 commit comments

Comments
 (0)