通过颤振应用程序,我需要定期发送带有回调的本地通知——在发送通知之前,每个周期/间隔都会调用回调。到目前为止,我已经尝试过 Timer 来安排定期的本地通知,但它在后台不起作用,即当应用程序关闭时。我也试过flutterLocalNotificationsPlugin.periodicallyShow,但是这个没有回调,在发送通知之前调用。最后,我尝试了 Firebase,但它需要在 firebase 控制台中设置通知。如何在数据库更改后获取带有已完成和待处理报告的回调通知。请针对上述问题提出解决方案。 这是我的代码:
import 'package:eclarity/pages/radiologist.dart';
import 'package:eclarity/pages/technici.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:flutter/cupertino.dart';
import 'dart:isolate';
import 'dart:math';
import 'dart:ui';
// import 'dart:ui';
import 'package:eclarity/pages/local_notifications.dart' as notify;
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State {
FlutterLocalNotificationsPlugin fltrNotification;
String _selectedParam;
String task;
String task1;
int task2;
String duration;
String numCompleted;
String numCompleted1;
String numPending;
String numPending1;
String role;
Timer timer;
TextEditingController timeController;
TextEditingController timeController1 = TextEditingController();
int val;
var url = "http://";
var data;
// Future<Radiologist> _future;
//Future<Radiologist> fetchReportStatus() async {
fetchReportStatus() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
int userPk = prefs?.getInt("userPk");
String startDate2 = prefs?.getString("notifyDateTime");
String startDate = prefs?.getString("loginDateTime");
var currentTime =
DateFormat('yyyy-MM-dd hh:mm:ss a').format(DateTime.now());
String role = prefs?.getString("role");
bool userIsTechnician = true;
if (role == "ROLE_RADIOLOGIST") {
userIsTechnician = false;
}
//userIsTechnician
Map data1 = {
'authUserPk': userPk,
"startDate": startDate,
"endDate": currentTime,
"userIsTechnician": userIsTechnician
};
String body1 = json.encode(data1);
final response = await http.post(url,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8'
},
body: body1);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
if (userIsTechnician) {
Technici r = Technici.fromJson(json.decode(response.body));
this.numCompleted = r.numCompleted;
this.numPending = r.numPending;
print("tech===============" + response.body);
} else {
Radiologist r = Radiologist.fromJson(json.decode(response.body));
this.numCompleted = r.numCompleted;
this.numPending = r.numPending;
print("rad===============" + response.body);
}
//return Radiologist.fromJson(json.decode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load report count');
}
}
/// The name associated with the UI isolate's [SendPort].
String isolateName = 'isolate';
// /// A port used to communicate from a background isolate to the UI isolate.
final ReceivePort port = ReceivePort();
static SendPort uiSendPort;
Future<void> showNotification(data) async {
print(data);
var rand = Random();
var hash = rand.nextInt(100);
DateTime now = DateTime.now().toUtc().add(Duration(seconds: 1));
await notify.singleNotification(
now,
"Hello $hash",
"This is hello message",
hash,
);
}
// The callback for our alarm
Future<void> callback() async {
print('Alarm fired!');
// // This will be null if we're running in the background.
uiSendPort ??= IsolateNameServer.lookupPortByName(isolateName);
uiSendPort?.send("hi");
}
@override
void initState() {
super.initState();
// _future =
// fetchReportStatus();
// repeatNotification();
//_showNotification();
port.listen((data) async => await showNotification(data));
runAlarm();
WidgetsBinding.instance.addPostFrameCallback((_) async {
timeController1.text = await getPrefForTimer3();
});
getPrefForTimer2().then((s) {
task1 = s.toString();
});
getPrefForDuration().then((s) {
_selectedParam = s;
});
var androidInitilize = new AndroidInitializationSettings('app_icon');
var iOSinitilize = new IOSInitializationSettings();
var initilizationsSettings = new InitializationSettings(
android: androidInitilize, iOS: iOSinitilize);
fltrNotification = new FlutterLocalNotificationsPlugin();
fltrNotification.initialize(initilizationsSettings,
onSelectNotification: notificationSelected);
setDurationAndShowNotification();
// timerNotification(false);
}
void runAlarm() async {
await AndroidAlarmManager.periodic(
Duration(seconds: 1),
0,
callback,
rescheduleOnReboot: true,
exact: true,
wakeup: true,
);
print("OK");
}
Future<String> getPrefForTimer3() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
int taskInt = prefs.getInt("task") ?? 30;
this.task1 = taskInt.toString();
return this.task1;
}
Future<int> getPrefForTimer1() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
int taskInt = prefs.getInt("task") ?? 30;
this.task1 = taskInt.toString();
return taskInt;
}
Future<int> getPrefForTimer2() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
int taskInt = prefs.getInt("task") ?? 30;
task1 = taskInt.toString();
return taskInt;
}
setPrefForTimer1(int val) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// setState(() {
prefs.setInt("task", val);
// });
}
Future<String> getPrefForDuration() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
duration = prefs.getString("duration").toString() ?? "Minutes";
});
return duration;
}
setPrefForDuration(String val) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
//setState(() {
prefs.setString("duration", val);
// });
}
getPrefForNumPending() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
this.numPending1 = prefs.getInt("numPending").toString() ?? "-1";
}
setPrefForNumPending(String val) async {
if (val == null) {return;}
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt("numPending", int.parse(val));
}
getPrefForNumCompleted() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
this.numCompleted1 = prefs.getInt("numCompleted").toString() ?? "0";
}
setPrefForNumCompleted(String val) async {
if (val == null) {return;}
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt("numCompleted", int.parse(val));
}
Future<bool> getUserIsTechnician() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String role = prefs?.getString("role");
bool userIsTechnician = true;
if (role == "ROLE_RADIOLOGIST") {
userIsTechnician = false;
}
return userIsTechnician;
}
timerNotificationRestart() {
if (this.task1 != null) {
setPrefForTimer1(int.parse(this.task1));
}
//timerNotification(true);
}
timerNotification1(bool stop) {
if (stop && this.timer != null) {
this.timer.cancel();
}
//getPrefForTimer1();
if (this.task1 == null) {
this.task2 = 30;
} else {
this.task2 = int.parse(task1);
}
Duration duration;
if (_selectedParam == "Hour") {
duration = Duration(hours: this.task2);
} else {
duration = Duration(minutes: this.task2);
}
bool isStopped = false;
this.timer = Timer.periodic(duration, (timer1) async {
// Make a local notification
if (isStopped) {
timer1.cancel();
}
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your channel id', 'your channel name', 'your channel description',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics);
await fetchReportStatus();
var value = await getUserIsTechnician();
if (!value) {
getPrefForNumPending();
bool sendNotification = false;
if (this.numPending1 != null && this.numPending != null
&& this.numPending != this.numPending1) {
sendNotification = true;
} else if (this.numPending1 == null) {
sendNotification = true;
}
setPrefForNumPending(this.numPending);
if (sendNotification) {
await fltrNotification.show(
0, "",
// "# Report Completed :" +
// this.numCompleted +
// "\n",
"# Report Pending : " +
this.numPending, platformChannelSpecifics,
payload: 'item x');
}
} else {
getPrefForNumCompleted();
bool sendNotification = false;
if (this.numCompleted1 != null && this.numCompleted != null
&& this.numCompleted != this.numCompleted1) {
sendNotification = true;
} else if (this.numCompleted1 == null) {
sendNotification = true;
}
setPrefForNumCompleted(this.numCompleted);
if (sendNotification) {
await fltrNotification.show(
0, "",
// "# Report Completed :" +
// this.numCompleted +
// "\n",
"# Report Completed : " +
this.numCompleted, platformChannelSpecifics,
payload: 'item x');
}
}
});
}
setDurationAndShowNotification() async {
await fltrNotification.cancelAll();
//await fltrNotification.cancel(1);
showNotification1();
}
showNotification1() async {
// var scheduledNotificationDateTime =
// new DateTime.now().add(new Duration(seconds: 5));
// Show a notification every minute with the first appearance happening a minute after invoking the method
var androidPlatformChannelSpecifics =
new AndroidNotificationDetails('repeating channel id 1',
'repeating channel name 1', 'repeating description 1');
var iOSPlatformChannelSpecifics =
new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics);
await fetchReportStatus();
var value = await getUserIsTechnician();
var interval;
if (_selectedParam == "Hour") {
interval = RepeatInterval.hourly;
} else {
interval = RepeatInterval.everyMinute;
}
if (!value) {
await getPrefForNumPending();
bool sendNotification = false;
if (this.numPending1 != null && this.numPending != null
&& this.numPending != this.numPending1) {
sendNotification = true;
} else if (this.numPending1 == null) {
sendNotification = true;
}
print("=========== About to send Rad Notification");
print("num pending ===== " + this.numPending);
print("num pending1 ===== " + this.numPending1);
print("sendNotification ===== " + sendNotification.toString());
setPrefForNumPending(this.numPending);
if (sendNotification) {
await fltrNotification.periodicallyShow(
0, "eClarity Reprot Status",
// "# Report Completed :" +
// this.numCompleted +
// "\n",
"# Report Pending : " + this.numPending,
interval, platformChannelSpecifics,
);
}
} else {
getPrefForNumCompleted();
bool sendNotification = false;
if (this.numCompleted1 != null && this.numCompleted != null
&& this.numCompleted != this.numCompleted1) {
sendNotification = true;
} else if (this.numCompleted1 == null) {
sendNotification = true;
}
print("=========== About to send Rad Notification");
print("num completed ===== " + this.numCompleted.toString());
print("num completed1 ===== " + this.numCompleted1.toString());
print("sendNotification ===== " + sendNotification.toString());
setPrefForNumCompleted(this.numCompleted);
if (sendNotification) {
await fltrNotification.periodicallyShow(
0, "eClarity Reprot Status",
// "# Report Completed :" +
// this.numCompleted +
// "\n",
"# Report Completed : " +
this.numCompleted, interval, platformChannelSpecifics,
);
}
}
}```