Showing
1 changed file
with
341 additions
and
2 deletions
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:flutter/services.dart'; | 2 | import 'package:flutter/services.dart'; |
3 | import '../../shared/colors.dart'; | 3 | import '../../shared/colors.dart'; |
4 | +import 'package:rxdart/subjects.dart'; | ||
4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 5 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
6 | +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; | ||
7 | +import 'package:flutter_application_1/src/screens/SettingPage.dart'; | ||
8 | +import 'package:flutter/cupertino.dart'; | ||
9 | +import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; | ||
10 | + | ||
11 | +final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = | ||
12 | + FlutterLocalNotificationsPlugin(); | ||
13 | +// Streams are created so that app can respond to notification-related events since the plugin is initialised in the `main` function | ||
14 | +final BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject = | ||
15 | + BehaviorSubject<ReceivedNotification>(); | ||
16 | + | ||
17 | +final BehaviorSubject<String> selectNotificationSubject = | ||
18 | + BehaviorSubject<String>(); | ||
19 | + | ||
20 | +NotificationAppLaunchDetails notificationAppLaunchDetails; | ||
21 | + | ||
22 | +class ReceivedNotification { | ||
23 | + final int id; | ||
24 | + final String title; | ||
25 | + final String body; | ||
26 | + final String payload; | ||
27 | + | ||
28 | + ReceivedNotification({ | ||
29 | + @required this.id, | ||
30 | + @required this.title, | ||
31 | + @required this.body, | ||
32 | + @required this.payload, | ||
33 | + }); | ||
34 | +} | ||
5 | 35 | ||
6 | class Alarm extends StatefulWidget { | 36 | class Alarm extends StatefulWidget { |
7 | @override | 37 | @override |
... | @@ -9,16 +39,325 @@ class Alarm extends StatefulWidget { | ... | @@ -9,16 +39,325 @@ class Alarm extends StatefulWidget { |
9 | } | 39 | } |
10 | 40 | ||
11 | class _AlarmnState extends State<Alarm> { | 41 | class _AlarmnState extends State<Alarm> { |
42 | + FlutterLocalNotificationsPlugin fltrNotification; | ||
43 | + | ||
44 | + void initState() { | ||
45 | + super.initState(); | ||
46 | + | ||
47 | + main(); | ||
48 | + } | ||
49 | + | ||
50 | + Future<void> main() async { | ||
51 | + // needed if you intend to initialize in the `main` function | ||
52 | + WidgetsFlutterBinding.ensureInitialized(); | ||
53 | + // NOTE: if you want to find out if the app was launched via notification then you could use the following call and then do something like | ||
54 | + // change the default route of the app | ||
55 | + // var notificationAppLaunchDetails = | ||
56 | + // await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); | ||
57 | + | ||
58 | + var initializationSettingsAndroid = | ||
59 | + new AndroidInitializationSettings('app_icon'); | ||
60 | + var initializationSettingsIOS = IOSInitializationSettings( | ||
61 | + requestAlertPermission: true, | ||
62 | + requestBadgePermission: true, | ||
63 | + requestSoundPermission: true, | ||
64 | + onDidReceiveLocalNotification: | ||
65 | + (int id, String title, String body, String payload) async {}); | ||
66 | + var initializationSettings = InitializationSettings( | ||
67 | + initializationSettingsAndroid, initializationSettingsIOS); | ||
68 | + await flutterLocalNotificationsPlugin.initialize(initializationSettings, | ||
69 | + onSelectNotification: (String payload) async { | ||
70 | + if (payload != null) { | ||
71 | + debugPrint('notification payload: ' + payload); | ||
72 | + } | ||
73 | + }); | ||
74 | + } | ||
75 | + | ||
76 | + void _requestIOSPermissions() { | ||
77 | + flutterLocalNotificationsPlugin | ||
78 | + .resolvePlatformSpecificImplementation< | ||
79 | + IOSFlutterLocalNotificationsPlugin>() | ||
80 | + ?.requestPermissions( | ||
81 | + alert: true, | ||
82 | + badge: true, | ||
83 | + sound: true, | ||
84 | + ); | ||
85 | + } | ||
86 | + | ||
87 | + void _configureDidReceiveLocalNotificationSubject() { | ||
88 | + didReceiveLocalNotificationSubject.stream | ||
89 | + .listen((ReceivedNotification receivedNotification) async { | ||
90 | + await showDialog( | ||
91 | + context: context, | ||
92 | + builder: (BuildContext context) => CupertinoAlertDialog( | ||
93 | + title: receivedNotification.title != null | ||
94 | + ? Text(receivedNotification.title) | ||
95 | + : null, | ||
96 | + content: receivedNotification.body != null | ||
97 | + ? Text(receivedNotification.body) | ||
98 | + : null, | ||
99 | + actions: [ | ||
100 | + CupertinoDialogAction( | ||
101 | + isDefaultAction: true, | ||
102 | + child: Text('Ok'), | ||
103 | + onPressed: () async { | ||
104 | + Navigator.of(context, rootNavigator: true).pop(); | ||
105 | + await Navigator.push( | ||
106 | + context, | ||
107 | + MaterialPageRoute( | ||
108 | + builder: (context) => | ||
109 | + SecondScreen(receivedNotification.payload), | ||
110 | + ), | ||
111 | + ); | ||
112 | + }, | ||
113 | + ) | ||
114 | + ], | ||
115 | + ), | ||
116 | + ); | ||
117 | + }); | ||
118 | + } | ||
119 | + | ||
120 | + void _configureSelectNotificationSubject() { | ||
121 | + selectNotificationSubject.stream.listen((String payload) async { | ||
122 | + await Navigator.push( | ||
123 | + context, | ||
124 | + MaterialPageRoute(builder: (context) => SecondScreen(payload)), | ||
125 | + ); | ||
126 | + }); | ||
127 | + } | ||
128 | + | ||
129 | + @override | ||
130 | + void dispose() { | ||
131 | + didReceiveLocalNotificationSubject.close(); | ||
132 | + selectNotificationSubject.close(); | ||
133 | + super.dispose(); | ||
134 | + } | ||
135 | + | ||
12 | Widget build(BuildContext context) { | 136 | Widget build(BuildContext context) { |
13 | final Size size = MediaQuery.of(context).size; | 137 | final Size size = MediaQuery.of(context).size; |
14 | return MaterialApp( | 138 | return MaterialApp( |
15 | title: 'Welcome to Flutter', | 139 | title: 'Welcome to Flutter', |
16 | home: Scaffold( | 140 | home: Scaffold( |
17 | appBar: AppBar( | 141 | appBar: AppBar( |
18 | - title: Text('Welcome to Flutter'), | 142 | + iconTheme: IconThemeData(color: Colors.black), |
143 | + backgroundColor: Colors.white, | ||
144 | + title: Text( | ||
145 | + 'Smart Medicine Box', | ||
146 | + style: TextStyle( | ||
147 | + color: Colors.black, | ||
148 | + fontSize: 20, | ||
149 | + fontFamily: 'Noto', | ||
150 | + fontWeight: FontWeight.bold), | ||
151 | + ), | ||
152 | + actions: [ | ||
153 | + IconButton( | ||
154 | + icon: Icon( | ||
155 | + Icons.settings, | ||
156 | + color: Colors.black, | ||
157 | + ), | ||
158 | + onPressed: () { | ||
159 | + Navigator.push( | ||
160 | + context, | ||
161 | + MaterialPageRoute( | ||
162 | + builder: (BuildContext context) => SettingPage(), | ||
163 | + )); | ||
164 | + }, | ||
165 | + ) | ||
166 | + ], | ||
167 | + ), | ||
168 | + drawer: Drawer( | ||
169 | + child: ListView( | ||
170 | + children: [ | ||
171 | + DrawerHeader( | ||
172 | + child: Text('Drawer Header'), | ||
173 | + decoration: BoxDecoration( | ||
174 | + color: Colors.blue, | ||
175 | + ), | ||
176 | + ), | ||
177 | + ListTile( | ||
178 | + title: Text('Test 1'), | ||
179 | + onTap: () {}, | ||
180 | + ), | ||
181 | + ListTile( | ||
182 | + title: Text('Test 2'), | ||
183 | + onTap: () {}, | ||
184 | + ), | ||
185 | + ListTile( | ||
186 | + title: Text('Test 3'), | ||
187 | + onTap: () {}, | ||
188 | + ), | ||
189 | + ], | ||
190 | + ), | ||
191 | + ), | ||
192 | + body: FlatButton( | ||
193 | + height: size.height * 0.07, | ||
194 | + onPressed: () { | ||
195 | + _showDailyAtTime(1, 2); | ||
196 | + }, | ||
197 | + child: Text( | ||
198 | + '알람 설정', | ||
199 | + textScaleFactor: 1.0, | ||
200 | + style: TextStyle( | ||
201 | + color: Colors.white, | ||
202 | + fontSize: 24, | ||
203 | + fontFamily: 'Noto', | ||
204 | + fontWeight: FontWeight.bold), | ||
205 | + ), | ||
206 | + color: Color(0xff8E97FD), | ||
207 | + shape: | ||
208 | + RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)), | ||
209 | + ), | ||
210 | + ), | ||
211 | + ); | ||
212 | + } | ||
213 | + | ||
214 | + Future<void> _cancelNotification() async { | ||
215 | + await flutterLocalNotificationsPlugin.cancel(0); | ||
216 | + } | ||
217 | + | ||
218 | + Future<void> _showTimeoutNotification() async { | ||
219 | + var androidPlatformChannelSpecifics = AndroidNotificationDetails( | ||
220 | + 'silent channel id', | ||
221 | + 'silent channel name', | ||
222 | + 'silent channel description', | ||
223 | + timeoutAfter: 3000, | ||
224 | + styleInformation: DefaultStyleInformation(true, true)); | ||
225 | + var iOSPlatformChannelSpecifics = | ||
226 | + IOSNotificationDetails(presentSound: false); | ||
227 | + var platformChannelSpecifics = NotificationDetails( | ||
228 | + androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); | ||
229 | + await flutterLocalNotificationsPlugin.show(0, 'timeout notification', | ||
230 | + 'Times out after 3 seconds', platformChannelSpecifics); | ||
231 | + } | ||
232 | + | ||
233 | + Future<void> _cancelAllNotifications() async { | ||
234 | + await flutterLocalNotificationsPlugin.cancelAll(); | ||
235 | + } | ||
236 | + | ||
237 | + /// 매일 지정된 시간에 Alarm 을 트는 Function | ||
238 | + Future<void> _showDailyAtTime(int a, int b) async { | ||
239 | + var time = Time(11, 24, 0); | ||
240 | + var androidPlatformChannelSpecifics = AndroidNotificationDetails( | ||
241 | + 'repeatDailyAtTime channel id', | ||
242 | + 'repeatDailyAtTime channel name', | ||
243 | + 'repeatDailyAtTime description'); | ||
244 | + var iOSPlatformChannelSpecifics = IOSNotificationDetails(); | ||
245 | + var platformChannelSpecifics = NotificationDetails( | ||
246 | + androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); | ||
247 | + await flutterLocalNotificationsPlugin.showDailyAtTime( | ||
248 | + 1, | ||
249 | + '알람 시간 알림 ', | ||
250 | + '설정하신 시간인 ${_toTwoDigitString(time.hour)}시 ${_toTwoDigitString(time.minute)}분입니다.', | ||
251 | + time, | ||
252 | + platformChannelSpecifics); | ||
253 | + | ||
254 | + var pendingNotificationRequests = | ||
255 | + await flutterLocalNotificationsPlugin.pendingNotificationRequests(); | ||
256 | + | ||
257 | + print(pendingNotificationRequests.toList()); | ||
258 | + } | ||
259 | + | ||
260 | + /// weekday 가 1부터 7순으로 일 월 화 수 목 금 토 일 순서로 구성이 되어 있음 이에 따라 설정한 Weekday time 에 학습 알람을 뛰어주는 역할을 해주는 함수 | ||
261 | + Future<void> _showWeeklyAtDayAndTime( | ||
262 | + int a, int b, int weekday, int index, int idindex) async { | ||
263 | + print(index + idindex); | ||
264 | + | ||
265 | + Day setDay; | ||
266 | + | ||
267 | + if (weekday == 1) { | ||
268 | + setDay = Day.Monday; | ||
269 | + } else if (weekday == 2) { | ||
270 | + setDay = Day.Tuesday; | ||
271 | + } else if (weekday == 3) { | ||
272 | + setDay = Day.Wednesday; | ||
273 | + } else if (weekday == 4) { | ||
274 | + setDay = Day.Thursday; | ||
275 | + } else if (weekday == 5) { | ||
276 | + setDay = Day.Friday; | ||
277 | + } else if (weekday == 6) { | ||
278 | + setDay = Day.Saturday; | ||
279 | + } else if (weekday == 7) { | ||
280 | + setDay = Day.Sunday; | ||
281 | + } | ||
282 | + | ||
283 | + var time = Time(a, b, 0); | ||
284 | + var androidPlatformChannelSpecifics = AndroidNotificationDetails( | ||
285 | + 'show weekly channel id', | ||
286 | + 'show weekly channel name', | ||
287 | + 'show weekly description'); | ||
288 | + var iOSPlatformChannelSpecifics = IOSNotificationDetails(); | ||
289 | + var platformChannelSpecifics = NotificationDetails( | ||
290 | + androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); | ||
291 | + await flutterLocalNotificationsPlugin.showWeeklyAtDayAndTime( | ||
292 | + index + idindex, | ||
293 | + '약통 알람 ', | ||
294 | + '알약 섭취 시간인 ${_toTwoDigitString(time.hour)}:${_toTwoDigitString(time.minute)}이 되었습니다.', | ||
295 | + setDay, | ||
296 | + time, | ||
297 | + platformChannelSpecifics); | ||
298 | + } | ||
299 | + | ||
300 | + String _toTwoDigitString(int value) { | ||
301 | + return value.toString().padLeft(2, '0'); | ||
302 | + } | ||
303 | + | ||
304 | + Future<void> onDidReceiveLocalNotification( | ||
305 | + int id, String title, String body, String payload) async { | ||
306 | + // display a dialog with the notification details, tap ok to go to another page | ||
307 | + await showDialog( | ||
308 | + context: context, | ||
309 | + builder: (BuildContext context) => CupertinoAlertDialog( | ||
310 | + title: title != null ? Text(title) : null, | ||
311 | + content: body != null ? Text(body) : null, | ||
312 | + actions: [ | ||
313 | + CupertinoDialogAction( | ||
314 | + isDefaultAction: true, | ||
315 | + child: Text('Ok'), | ||
316 | + onPressed: () async { | ||
317 | + Navigator.of(context, rootNavigator: true).pop(); | ||
318 | + await Navigator.push( | ||
319 | + context, | ||
320 | + MaterialPageRoute( | ||
321 | + builder: (context) => SecondScreen(payload), | ||
322 | + ), | ||
323 | + ); | ||
324 | + }, | ||
325 | + ) | ||
326 | + ], | ||
327 | + ), | ||
328 | + ); | ||
329 | + } | ||
330 | +} | ||
331 | + | ||
332 | +class SecondScreen extends StatefulWidget { | ||
333 | + SecondScreen(this.payload); | ||
334 | + | ||
335 | + final String payload; | ||
336 | + | ||
337 | + @override | ||
338 | + State<StatefulWidget> createState() => SecondScreenState(); | ||
339 | +} | ||
340 | + | ||
341 | +class SecondScreenState extends State<SecondScreen> { | ||
342 | + String _payload; | ||
343 | + @override | ||
344 | + void initState() { | ||
345 | + super.initState(); | ||
346 | + _payload = widget.payload; | ||
347 | + } | ||
348 | + | ||
349 | + @override | ||
350 | + Widget build(BuildContext context) { | ||
351 | + return Scaffold( | ||
352 | + appBar: AppBar( | ||
353 | + title: Text('Second Screen with payload: ${(_payload ?? '')}'), | ||
19 | ), | 354 | ), |
20 | body: Center( | 355 | body: Center( |
21 | - child: Text('약병 내부 페이지 작업 영역'), | 356 | + child: RaisedButton( |
357 | + onPressed: () { | ||
358 | + Navigator.pop(context); | ||
359 | + }, | ||
360 | + child: Text('Go back!'), | ||
22 | ), | 361 | ), |
23 | ), | 362 | ), |
24 | ); | 363 | ); | ... | ... |
-
Please register or login to post a comment