maui-media-picker
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese.NET MAUI Media Picker Skill
.NET MAUI Media Picker 使用指南
Core API
核心API
Use to pick or capture photos and videos. All methods must run on the UI thread.
MediaPicker.Default使用来选择或拍摄照片和视频。所有方法必须在UI线程上运行。
MediaPicker.DefaultSingle-select methods (all .NET versions)
单选方法(所有.NET版本)
| Method | Purpose |
|---|---|
| Pick one photo from gallery |
| Pick one video from gallery |
| Capture a photo with the camera |
| Capture a video with the camera |
All return . A null result means the user cancelled.
Task<FileResult?>| 方法 | 用途 |
|---|---|
| 从相册选择一张照片 |
| 从相册选择一段视频 |
| 使用相机拍摄一张照片 |
| 使用相机拍摄一段视频 |
所有方法返回。返回null表示用户已取消操作。
Task<FileResult?>Multi-select methods (.NET 10+)
多选方法(.NET 10及以上版本)
| Method | Purpose |
|---|---|
| Pick multiple photos |
| Pick multiple videos |
These return . An empty list means the user cancelled.
Task<IEnumerable<FileResult>>| 方法 | 用途 |
|---|---|
| 选择多张照片 |
| 选择多段视频 |
这些方法返回。返回空列表表示用户已取消操作。
Task<IEnumerable<FileResult>>MediaPickerOptions (.NET 10+)
MediaPickerOptions(.NET 10及以上版本)
Pass to any pick/capture method to control behavior:
MediaPickerOptionscsharp
var options = new MediaPickerOptions
{
Title = "Select photos", // Picker dialog title
SelectionLimit = 5, // Max items (0 = unlimited; multi-select only)
MaximumWidth = 1024, // Resize max width in pixels
MaximumHeight = 1024, // Resize max height in pixels
CompressionQuality = 80, // JPEG quality 0–100
RotateImage = true, // Auto-rotate per EXIF
PreserveMetaData = true // Keep EXIF/metadata
};
var photos = await MediaPicker.Default.PickPhotosAsync(options);Platform note: Android and Windows may not enforce. Always validate the count in your code.SelectionLimit
将传递给任何选择/拍摄方法以控制行为:
MediaPickerOptionscsharp
var options = new MediaPickerOptions
{
Title = "Select photos", // Picker dialog title
SelectionLimit = 5, // Max items (0 = unlimited; multi-select only)
MaximumWidth = 1024, // Resize max width in pixels
MaximumHeight = 1024, // Resize max height in pixels
CompressionQuality = 80, // JPEG quality 0–100
RotateImage = true, // Auto-rotate per EXIF
PreserveMetaData = true // Keep EXIF/metadata
};
var photos = await MediaPicker.Default.PickPhotosAsync(options);平台说明: Android和Windows可能不强制执行。请始终在代码中验证返回数量。SelectionLimit
FileResult usage
FileResult 使用
csharp
var photo = await MediaPicker.Default.PickPhotoAsync();
if (photo is null)
return; // user cancelled
// Read the stream
using var stream = await photo.OpenReadAsync();
// Useful properties
string fullPath = photo.FullPath;
string fileName = photo.FileName;
string contentType = photo.ContentType;csharp
var photo = await MediaPicker.Default.PickPhotoAsync();
if (photo is null)
return; // user cancelled
// Read the stream
using var stream = await photo.OpenReadAsync();
// Useful properties
string fullPath = photo.FullPath;
string fileName = photo.FileName;
string contentType = photo.ContentType;Save to app storage
保存到应用存储
csharp
async Task<string> SaveToAppDataAsync(FileResult fileResult)
{
var targetPath = Path.Combine(FileSystem.AppDataDirectory, fileResult.FileName);
using var sourceStream = await fileResult.OpenReadAsync();
using var targetStream = File.OpenWrite(targetPath);
await sourceStream.CopyToAsync(targetStream);
return targetPath;
}csharp
async Task<string> SaveToAppDataAsync(FileResult fileResult)
{
var targetPath = Path.Combine(FileSystem.AppDataDirectory, fileResult.FileName);
using var sourceStream = await fileResult.OpenReadAsync();
using var targetStream = File.OpenWrite(targetPath);
await sourceStream.CopyToAsync(targetStream);
return targetPath;
}Platform permissions
平台权限
Android
Android
Add to :
Platforms/Android/AndroidManifest.xmlxml
<!-- Camera capture -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Storage: API ≤ 32 (Android 12 and below) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<!-- Storage: API ≥ 33 (Android 13+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />Also add inside :
<application>xml
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>添加以下内容到:
Platforms/Android/AndroidManifest.xmlxml
<!-- Camera capture -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Storage: API ≤ 32 (Android 12 and below) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<!-- Storage: API ≥ 33 (Android 13+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />同时在标签内添加:
<application>xml
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>iOS / Mac Catalyst
iOS / Mac Catalyst
Add to (and ):
Platforms/iOS/Info.plistPlatforms/MacCatalyst/Info.plistxml
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to take photos</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access to record video</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs photo library access to pick media</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs permission to save photos</string>添加以下内容到(以及):
Platforms/iOS/Info.plistPlatforms/MacCatalyst/Info.plistxml
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to take photos</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access to record video</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs photo library access to pick media</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs permission to save photos</string>Windows
Windows
No additional permissions required.
无需额外权限。
Check availability before capture
拍摄前检查可用性
csharp
if (MediaPicker.Default.IsCaptureSupported)
{
var photo = await MediaPicker.Default.CapturePhotoAsync();
// ...
}csharp
if (MediaPicker.Default.IsCaptureSupported)
{
var photo = await MediaPicker.Default.CapturePhotoAsync();
// ...
}Multi-select example (.NET 10+)
多选示例(.NET 10及以上版本)
csharp
var options = new MediaPickerOptions { SelectionLimit = 10 };
var results = await MediaPicker.Default.PickPhotosAsync(options);
if (!results.Any())
return; // user cancelled
foreach (var file in results)
{
using var stream = await file.OpenReadAsync();
// process each selected photo
}csharp
var options = new MediaPickerOptions { SelectionLimit = 10 };
var results = await MediaPicker.Default.PickPhotosAsync(options);
if (!results.Any())
return; // user cancelled
foreach (var file in results)
{
using var stream = await file.OpenReadAsync();
// process each selected photo
}Key rules
关键规则
- Always call media picker methods on the main/UI thread.
- Single-select cancellation returns null; multi-select returns an empty list.
- Use before calling capture methods.
IsCaptureSupported - Android/Windows may ignore — validate result count yourself.
SelectionLimit - gives a stream; dispose it when done.
OpenReadAsync() - Save files to for persistent app-local storage.
FileSystem.AppDataDirectory
- 始终在主线程/UI线程上调用媒体选择器方法。
- 单选操作取消返回null;多选操作取消返回空列表。
- 调用拍摄方法前请使用检查可用性。
IsCaptureSupported - Android/Windows可能会忽略——请自行验证结果数量。
SelectionLimit - 返回一个流;使用完毕后请释放它。
OpenReadAsync() - 将文件保存到以获得持久的应用本地存储。
FileSystem.AppDataDirectory