flutter - 如何检查给定的路径是图像还是视频?
问题描述
我从 file_picker 颤振包中获取文件路径。我想知道给定的路径是图像还是视频?如果提供的路径是图像或视频,我怎么知道。
解决方案
请使用包https://pub.dev/packages/mime
扩展和 mime 类型映射
https://github.com/dart-lang/mime/blob/master/lib/src/default_extension_map.dart
video/* 表示视频和image/* 表示图像
代码片段
String mimeStr = lookupMimeType(_path);
var fileType = mimeStr.split('/');
print('file type ${fileType}');
完整代码,文件选择器演示在函数 _openFileExplorer() 中添加检查 mime 类型
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:file_picker/file_picker.dart';
import 'package:mime/mime.dart';
class FilePickerDemo extends StatefulWidget {
@override
_FilePickerDemoState createState() => new _FilePickerDemoState();
}
class _FilePickerDemoState extends State<FilePickerDemo> {
String _fileName;
String _path;
Map<String, String> _paths;
String _extension;
bool _loadingPath = false;
bool _multiPick = false;
bool _hasValidMime = false;
FileType _pickingType;
TextEditingController _controller = new TextEditingController();
@override
void initState() {
super.initState();
_controller.addListener(() => _extension = _controller.text);
}
void _openFileExplorer() async {
if (_pickingType != FileType.CUSTOM || _hasValidMime) {
setState(() => _loadingPath = true);
try {
if (_multiPick) {
_path = null;
_paths = await FilePicker.getMultiFilePath(
type: _pickingType, fileExtension: _extension);
} else {
_paths = null;
_path = await FilePicker.getFilePath(
type: _pickingType, fileExtension: _extension);
String mimeStr = lookupMimeType(_path);
var fileType = mimeStr.split('/');
print('file type ${fileType}');
}
} on PlatformException catch (e) {
print("Unsupported operation" + e.toString());
}
if (!mounted) return;
setState(() {
_loadingPath = false;
_fileName = _path != null
? _path.split('/').last
: _paths != null ? _paths.keys.toString() : '...';
});
}
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('File Picker example app'),
),
body: new Center(
child: new Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: new SingleChildScrollView(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.only(top: 20.0),
child: new DropdownButton(
hint: new Text('LOAD PATH FROM'),
value: _pickingType,
items: <DropdownMenuItem>[
new DropdownMenuItem(
child: new Text('FROM AUDIO'),
value: FileType.AUDIO,
),
new DropdownMenuItem(
child: new Text('FROM IMAGE'),
value: FileType.IMAGE,
),
new DropdownMenuItem(
child: new Text('FROM VIDEO'),
value: FileType.VIDEO,
),
new DropdownMenuItem(
child: new Text('FROM ANY'),
value: FileType.ANY,
),
new DropdownMenuItem(
child: new Text('CUSTOM FORMAT'),
value: FileType.CUSTOM,
),
],
onChanged: (value) => setState(() {
_pickingType = value;
if (_pickingType != FileType.CUSTOM) {
_controller.text = _extension = '';
}
})),
),
new ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100.0),
child: _pickingType == FileType.CUSTOM
? new TextFormField(
maxLength: 15,
autovalidate: true,
controller: _controller,
decoration:
InputDecoration(labelText: 'File extension'),
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.none,
validator: (value) {
RegExp reg = new RegExp(r'[^a-zA-Z0-9]');
if (reg.hasMatch(value)) {
_hasValidMime = false;
return 'Invalid format';
}
_hasValidMime = true;
return null;
},
)
: new Container(),
),
new ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 200.0),
child: new SwitchListTile.adaptive(
title: new Text('Pick multiple files',
textAlign: TextAlign.right),
onChanged: (bool value) =>
setState(() => _multiPick = value),
value: _multiPick,
),
),
new Padding(
padding: const EdgeInsets.only(top: 50.0, bottom: 20.0),
child: new RaisedButton(
onPressed: () => _openFileExplorer(),
child: new Text("Open file picker"),
),
),
new Builder(
builder: (BuildContext context) => _loadingPath
? Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: const CircularProgressIndicator())
: _path != null || _paths != null
? new Container(
padding: const EdgeInsets.only(bottom: 30.0),
height: MediaQuery.of(context).size.height * 0.50,
child: new Scrollbar(
child: new ListView.separated(
itemCount: _paths != null && _paths.isNotEmpty
? _paths.length
: 1,
itemBuilder: (BuildContext context, int index) {
final bool isMultiPath =
_paths != null && _paths.isNotEmpty;
final String name = 'File $index: ' +
(isMultiPath
? _paths.keys.toList()[index]
: _fileName ?? '...');
final path = isMultiPath
? _paths.values.toList()[index].toString()
: _path;
return new ListTile(
title: new Text(
name,
),
subtitle: new Text(path),
);
},
separatorBuilder:
(BuildContext context, int index) =>
new Divider(),
)),
)
: new Container(),
),
],
),
),
)),
),
);
}
}
演示输出
I/flutter (21426): file type [image, png]
推荐阅读
- java - 飞溅结束时如何填充活动?
- spring - Spring Data 中给定的 id 不能为空
- vespa - 使用 vespa 实施引导导航
- ruby-on-rails - 基于Ruby中的两个字符串或参数从String中删除SubString
- azure-devops - Azure DevOps 发布管道:使用手动触发器让发布流经多个环境
- javascript - 如何将forEach值与jquery中选定的下拉值进行比较
- cassandra - 我们可以在 cassandra 中限制一个表只有有限数量的记录或行吗?
- web3 - 如何使用 tron-web 调用合约方法
- python - Pandas Group 然后滚动和求和得到错误的结果
- c# - 如何按他自己的属性和另一个列表中的属性对列表进行排序?