Flutter周期性闹钟功能插件periodic_alarm的使用
Flutter周期性闹钟功能插件periodic_alarm的使用
开始安装
在您的android/app/build.gradle
文件中,确保包含以下配置:
android {
compileSdkVersion 33
[...]
defaultConfig {
[...]
multiDexEnabled true
}
}
之后,在您的AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- For apps with targetSDK=31 (Android 12) -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
接着,在<application>
标签内添加以下服务和接收器:
<service
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false"/>
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
最后,将音频资源添加到项目中。
如何使用
在您的pubspec.yaml
文件中添加插件:
flutter pub add periodic_alarm
首先,在main
函数中初始化插件:
await PeriodicAlarm.init();
然后,定义闹钟设置:
final alarmSettings = AlarmSettings(
id: id,
dateTime: dateTime,
assetAudioPath: 'assets/alarm.mp3',
loopAudio: true,
fadeDuration: 3.0,
notificationTitle: '这是标题',
notificationBody: '这是内容',
enableNotificationOnKill: true,
monday: true,
tuesday : true,
wednesday : true,
thursday : true,
friday : true,
saturday : true,
sunday : true,
active : true,
);
最后,设置闹钟:
await PeriodicAlarm.setOneAlarm(alarmModel: alarmModel);
属性说明
属性 | 类型 | 描述 |
---|---|---|
id | int |
闹钟的唯一标识符。 |
dateTime | DateTime |
您希望闹钟响起的日期和时间。 |
assetAudioPath | String |
您希望用作铃声的音频资产路径。可以是本地资源或网络URL。 |
loopAudio | bool |
如果为真,则音频将无限重复播放,直到停止。 |
fadeDuration | double |
在多少秒内淡入淡出铃声音量。默认值为0,表示不淡入淡出。 |
notificationTitle | String |
当应用程序处于后台时触发的铃声通知标题。 |
notificationBody | String |
通知的内容。 |
enableNotificationOnKill | bool |
当应用程序被杀死时是否显示通知以警告用户可能无法响铃。默认启用。 |
完整示例
以下是完整的示例代码:
import 'package:flutter/material.dart';
import 'package:periodic_alarm/model/alarms_model.dart';
import 'dart:async';
import 'package:periodic_alarm/periodic_alarm.dart';
import 'package:periodic_alarm/services/alarm_notification.dart';
import 'package:periodic_alarm/services/alarm_storage.dart';
import 'package:periodic_alarm_example/view/alarm_screen.dart';
import 'package:periodic_alarm/src/android_alarm.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/alarmscreen': (context) => AlarmScreen()
},
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
[@override](/user/override)
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
StreamSubscription? _subscription;
StreamSubscription? _subscription2;
bool alarm = false;
bool alarm1 = false;
int? id;
[@override](/user/override)
void initState() {
super.initState();
// onRingingControl();
PeriodicAlarm.init();
configureSelectNotificationSubject();
}
[@override](/user/override)
void dispose() {
AndroidAlarm.audioPlayer.dispose();
super.dispose();
}
configureSelectNotificationSubject() {
_subscription2 ??= AlarmNotification.selectNotificationStream.stream
.listen((String? payload) async {
List<String> payloads = [];
AlarmModel? alarmModel;
payloads.add(payload!);
payloads.forEach((element) {
if (int.tryParse(element) != null) {
id = int.tryParse(element);
alarmModel = PeriodicAlarm.getAlarmWithId(id!);
setState(() {});
} else if (element == 'stop') {
PeriodicAlarm.stop(id!);
} else if (element == "") {
openAlarmScreen();
}
});
});
}
Future<void> setAlarm(int id, DateTime dt) async {
AlarmModel alarmModel = AlarmModel(
id: id,
dateTime: dt,
assetAudioPath: 'assets/0.mp3',
notificationTitle: '闹钟来电',
notificationBody: '点击关闭闹钟',
// monday: true,
// tuesday: true,
// wednesday: true,
// thursday: true,
// friday: true,
active: true,
musicTime: 1,
incMusicTime: 0.2272243957519531,
musicVolume: 1,
incMusicVolume:1);
if (alarmModel.days.contains(true)) {
PeriodicAlarm.setPeriodicAlarm(alarmModel: alarmModel);
} else {
PeriodicAlarm.setOneAlarm(alarmModel: alarmModel);
}
}
openAlarmScreen() async {
Future.delayed(Duration(seconds: 1), () async {
var alarms = await AlarmStorage.getAlarmRinging();
if (alarms.isNotEmpty) {
Navigator.pushNamed(context, '/alarmscreen');
}
});
}
onRingingControl() {
_subscription = PeriodicAlarm.ringStream.stream.listen(
(alarmModel) async {
openAlarmScreen();
// if (alarmModel.days.contains(true)) {
// alarmModel.setDateTime = alarmModel.dateTime.add(Duration(days: 1));
// PeriodicAlarm.setPeriodicAlarm(alarmModel: alarmModel);
// }
},
);
setState(() {});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: Center(
child: Switch(
value: alarm,
onChanged: (value) {
alarm = value;
setState(() {});
if (value) {
setAlarm(0, DateTime.parse('2023-06-21 16:12:00.000'));
// setAlarm(1, DateTime(2023, 4, 7, 21, 01, 00));
// setAlarm(1, DateTime(2023, 4, 7, 19, 54 ,00));
// setAlarm(1, 20);
}
},
),
),
);
}
}
更多关于Flutter周期性闹钟功能插件periodic_alarm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter周期性闹钟功能插件periodic_alarm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter中的periodic_alarm
插件来实现周期性闹钟功能的代码示例。请注意,由于Flutter和插件生态系统会随时间变化,请确保您使用的是最新版本的插件,并参考官方文档进行必要的调整。
首先,确保在pubspec.yaml
文件中添加periodic_alarm
插件依赖:
dependencies:
flutter:
sdk: flutter
periodic_alarm: ^最新版本号 # 请替换为实际最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,是一个完整的示例代码,展示了如何使用periodic_alarm
插件来设置周期性闹钟:
import 'package:flutter/material.dart';
import 'package:periodic_alarm/periodic_alarm.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Periodic Alarm Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AlarmScreen(),
);
}
}
class AlarmScreen extends StatefulWidget {
@override
_AlarmScreenState createState() => _AlarmScreenState();
}
class _AlarmScreenState extends State<AlarmScreen> {
String _alarmStatus = "Alarm not set";
@override
void initState() {
super.initState();
// 检查是否有已设置的周期性闹钟
_checkAndSetAlarm();
}
@override
void dispose() {
// 取消闹钟
PeriodicAlarm.cancel(alarmId: 1);
super.dispose();
}
Future<void> _checkAndSetAlarm() async {
bool isAlarmSet = await PeriodicAlarm.isAlarmSet(alarmId: 1);
if (isAlarmSet) {
setState(() {
_alarmStatus = "Alarm already set";
});
}
}
Future<void> _setPeriodicAlarm() async {
// 设置一个每秒触发一次的周期性闹钟
bool result = await PeriodicAlarm.setAlarm(
alarmId: 1,
repeatInterval: Duration(seconds: 1),
alarmCallback: () async {
// 闹钟触发时的回调
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Alarm Triggered"),
content: Text("This is a periodic alarm."),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
);
},
);
},
);
if (result) {
setState(() {
_alarmStatus = "Alarm set successfully";
});
} else {
setState(() {
_alarmStatus = "Failed to set alarm";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Periodic Alarm Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_alarmStatus,
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _setPeriodicAlarm,
child: Text('Set Periodic Alarm'),
),
],
),
),
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,它允许用户设置一个每秒触发一次的周期性闹钟。当闹钟触发时,会显示一个对话框。
注意:
PeriodicAlarm.setAlarm
方法用于设置周期性闹钟。alarmId
用于唯一标识闹钟,repeatInterval
指定了闹钟的触发间隔,alarmCallback
是闹钟触发时的回调函数。PeriodicAlarm.cancel
方法用于取消指定的闹钟。PeriodicAlarm.isAlarmSet
方法用于检查是否有已设置的闹钟。
由于periodic_alarm
插件可能需要特定的平台(如Android和iOS)权限和配置,请务必参考插件的官方文档进行必要的配置。此外,由于后台执行和电池优化策略的限制,某些设备或操作系统版本可能会限制或禁止后台任务的执行,这可能会影响闹钟的触发。