fix: file picker now shows subdirectories on Android

FileType.custom with allowedExtensions causes Android system picker
to hide subdirectories on some devices. Changed to FileType.any with
post-selection extension validation instead.

- Unsupported file types are skipped with a SnackBar hint
- Allowed: jpg, jpeg, png, gif, webp, pdf

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-28 06:02:47 -08:00
parent 4987cad881
commit 7e44ddc358
1 changed files with 16 additions and 4 deletions

View File

@ -209,18 +209,26 @@ class _ChatPageState extends ConsumerState<ChatPage> {
return; return;
} }
// Use FileType.any so the system picker shows subdirectories for navigation.
// We validate file extensions after selection.
final result = await FilePicker.platform.pickFiles( final result = await FilePicker.platform.pickFiles(
type: FileType.custom, type: FileType.any,
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf'],
allowMultiple: true, allowMultiple: true,
); );
if (result == null || result.files.isEmpty) return; if (result == null || result.files.isEmpty) return;
const allowedExts = {'jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf'};
int skipped = 0;
final toAdd = result.files.take(remaining); final toAdd = result.files.take(remaining);
for (final file in toAdd) { for (final file in toAdd) {
if (file.path == null) continue; if (file.path == null) continue;
final bytes = await File(file.path!).readAsBytes();
final ext = (file.extension ?? '').toLowerCase(); final ext = (file.extension ?? '').toLowerCase();
if (!allowedExts.contains(ext)) {
skipped++;
continue;
}
final bytes = await File(file.path!).readAsBytes();
final String mediaType; final String mediaType;
if (ext == 'pdf') { if (ext == 'pdf') {
mediaType = 'application/pdf'; mediaType = 'application/pdf';
@ -241,7 +249,11 @@ class _ChatPageState extends ConsumerState<ChatPage> {
} }
setState(() {}); setState(() {});
if (result.files.length > remaining && mounted) { if (skipped > 0 && mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('仅支持图片(jpg/png/gif/webp)和PDF文件')),
);
} else if (result.files.length > remaining && mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('已选择 $remaining 个,最多 $_maxAttachments')), SnackBar(content: Text('已选择 $remaining 个,最多 $_maxAttachments')),
); );