Dart中实现只能获取一部分手机权限 如果需要获取通话状态需要结合Android 混合开发实现
- 使用dart实现简单的录音功能 设置打开软件后自动录音 10秒后结束录音并保存在本地
- 获取录音所需要的权限需要你在 Android 中的AndroidManifest.xml 中添加
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart'; //录音权限
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '录音demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: YourWidget(),
);
}
}
class YourWidget extends StatefulWidget {
@override
_YourWidgetState createState() => _YourWidgetState();
}
class _YourWidgetState extends State<YourWidget> {
bool _isRecording = false;
Timer? _timer;
int _seconds = 0;
FlutterSoundRecorder? _recorder;
String? _filePath;
@override
void initState() {
super.initState();
_requestPermissionsAndStartRecording();
}
void _requestPermissionsAndStartRecording() async {
Map<Permission, PermissionStatus> statuses = await [
Permission.microphone,
Permission.storage,
].request();
if (statuses[Permission.microphone]!.isGranted &&
statuses[Permission.storage]!.isGranted) {
_startRecording();
} else {
// 权限被拒绝
}
}
void _startRecording() async {
Directory? appDocDir = await getApplicationDocumentsDirectory();
String filePath = '${appDocDir.path}/recording.aac';
_recorder = FlutterSoundRecorder();
await _recorder!.openAudioSession();
await _recorder!.startRecorder(toFile: filePath);
setState(() {
_isRecording = true;
_seconds = 0; // 重置计时器
_filePath = filePath;
});
_timer = Timer.periodic(Duration(seconds: 1), (_) {
setState(() {
_seconds++;
});
if (_seconds == 10) {
_stopRecording();
}
});
}
void _stopRecording() async {
_recorder?.stopRecorder();
_recorder?.closeAudioSession();
setState(() {
_isRecording = false;
});
_timer?.cancel();
// 显示保存成功提示
String? savedPath = await _saveRecording();
if (savedPath != null) {
_showSaveSuccessSnackBar(savedPath);
} else {
_showSaveErrorSnackBar();
}
}
Future<String?> _saveRecording() async {
// 获取外部存储目录路径
Directory? externalDir = await getExternalStorageDirectory();
String targetPath = '${externalDir!.path}/recording.aac';
try {
// 复制录音文件到外部存储目录
File(_filePath!).copySync(targetPath);
return targetPath;
} catch (e) {
print('保存录音文件失败: $e');
return null;
}
}
void _showSaveSuccessSnackBar(String filePath) {
final snackBar = SnackBar(
content: Text('保存成功!文件位置:$filePath'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void _showSaveErrorSnackBar() {
final snackBar = SnackBar(
content: Text('保存失败,请重试!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
@override
void dispose() {
_timer?.cancel(); // 取消计时器
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Align(
alignment: Alignment.center,
child: Text('Recording time: $_seconds seconds'),
),
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
onPressed: _isRecording ? null : _stopRecording,
child: Text(_isRecording ? 'Recording...' : 'Stop Recording'),
),
),
],
),
);
}
}