我正在尝试使用flutter_local_notifications包通过我的应用程序推送本地通知,并且像在FlutterNotificationsPlugin上一样,不建议使用“ .schedule”,但我尝试使用“ .zonedSchedule”,但它需要TZDateTime值。
var androidDetails = AndroidNotificationDetails(t.id, "Task Notifier",
"Notifies if you have a task scheduled at a particular time");
var generalNotificationDetails =
NotificationDetails(android: androidDetails);
var now = DateTime.now();
var scheduledTime = DateTime(
now.year, now.month, _dayTasks.date.day, t.time.hour, t.time.minute)
.subtract(Duration(minutes: 5));
//use zonedSchedule once you figure out how to convert datetime to TZdatetime
// await notifications.zonedSchedule(
// 0, "Task", t.description, scheduledTime, generalNotificationDetails,
// androidAllowWhileIdle: true,
// uiLocalNotificationDateInterpretation:
// UILocalNotificationDateInterpretation.wallClockTime);
await notifications.schedule(0, "Ideal Day Task", t.description,
scheduledTime, generalNotificationDetails);
答案 0 :(得分:2)
实际上,zonedSchedule()需要TZDateTime值。我采用的方法是利用另一个包将原始DateTime值转换为TZDateTime值。以下是我使用的一种实现的摘录。看到第五行?它涉及到函数TZDateTime.from()。它会使用您最初使用的DateTime并将其转换为TZDateTime。但是,它需要您当前的位置。那就是类TimeZone的所在。
import 'package:timezone/timezone.dart' as tz;
:
:
:
final timeZone = TimeZone();
// The device's timezone.
String timeZoneName = await timeZone.getTimeZoneName();
// Find the 'current location'
final location = await timeZone.getLocation(timeZoneName);
final scheduledDate = tz.TZDateTime.from(dateTime, location);
try {
await _flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
body,
scheduledDate,
platformChannelSpecifics,
androidAllowWhileIdle: androidAllowWhileIdle,
payload: payload,
uiLocalNotificationDateInterpretation:
uiLocalNotificationDateInterpretation,
);
} catch (ex) {
id = -1;
}
return id;
我很快编写了TimeZone类。此类与另一个插件(flutter_native_timezone)配合使用,该插件可查找设备的“当前位置”并提供该语言环境的标准名称:
import 'package:timezone/data/latest.dart';
import 'package:timezone/timezone.dart' as t;
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
class TimeZone {
factory TimeZone() => _this ?? TimeZone._();
TimeZone._() {
initializeTimeZones();
}
static TimeZone _this;
Future<String> getTimeZoneName() async => FlutterNativeTimezone.getLocalTimezone();
Future<t.Location> getLocation([String timeZoneName]) async {
if(timeZoneName == null || timeZoneName.isEmpty){
timeZoneName = await getTimeZoneName();
}
return t.getLocation(timeZoneName);
}
}
使用该课程,你很好。
答案 1 :(得分:1)
我刚刚尝试解决相同的问题。要了解这一点,我们需要对平台渠道有基本的了解。
一旦我们了解了这一点,示例中的代码将变得更加易于理解: https://github.com/MaikuB/flutter_local_notifications/blob/1fe78b9d129d674cd97cfba49734577b24c56925/flutter_local_notifications/example/android/app/src/main/java/com/dexterous/flutterlocalnotificationsexample/MainActivity.java
实际概念:
首先,我们将需要像这样导入tz。这可以在您的main.dart或帮助文件中完成。
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
要从简单的dateTime创建TZDateTime
,我们将需要通过平台渠道查询设备时区。
Future<void> configureLocalTimeZone() async {
tz.initializeTimeZones();
final String timeZoneName = await platform.invokeMethod('getTimeZoneName');
tz.setLocalLocation(tz.getLocation(timeZoneName));
}
在特定于平台的实现中实现getTimeZoneName
的地方。
请务必在下一步之前致电configureLocalTimeZone
。
当我们想从TZDateTime
对象创建DateTime
时,我们通常可以这样做
var time = tz.TZDateTime.from(
scheduledNotificationDateTime,
tz.local,
);
完整的实现在以下示例代码中进行了展示: https://github.com/MaikuB/flutter_local_notifications/blob/1fe78b9d129d674cd97cfba49734577b24c56925/flutter_local_notifications/example/lib/main.dart
在我非常简单的工作流程(YMMV)中,我没有考虑过不同的情况。 希望这可以帮助! :)
答案 2 :(得分:1)
我也遇到了同样的问题并试图找到解决方案,但有些解决方案要么已经过时,要么正在使用不同的软件包。 zonedSchedule() 函数需要 TZDateTime。所以我们可以
Duration offsetTime= DateTime.now().timeZoneOffset;
这将为我们提供您的机器时间和 UTC 之间的差异,然后我们将从本地时间(默认为 UTC)中减去它
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
.
.
.
Future initializetimezone() async {
tz.initializeTimeZones();
}
Future<void> scheduleNotification()async{
await initializetimezone();
var androidChannel = AndroidNotificationDetails(
'App',
"Notifications",
'Customize',
importance: Importance.max,
priority: Priority.high,
playSound: true,
enableLights: true,
ongoing: false,
visibility: NotificationVisibility.public,
);
var iosChannel = IOSNotificationDetails();
var platfromChannel =
NotificationDetails(android: androidChannel, iOS: iosChannel);
// year, month, etc can manually entered or you can use
// DateTime.now() also for current time in local machine.
tz.TZDateTime zonedTime = tz.TZDateTime.local(year,month,day,hour,
minute).subtract(offsetTime);
await flutterLocalNotificationsPlugin.zonedSchedule(
0,
'Some Notification',
'Description',
zonedTime ,
platfromChannel,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
payload: 'Payload',
androidAllowWhileIdle: true,
);
}
我希望这会有所帮助。当 UTC 和本地机器之间的时差为正值 (+5:30:00.000000) 时,这对我有用,我不确定负时差国家/地区。