고원빈

[frontend] 2021-05-14

......@@ -42,3 +42,6 @@ appbar 관련 디자인은 추후 구현 예정
+ datetime picker widget을 이용하여 시간 선택 구현 예정
+ 알람 설정을 위한 Android Mainfest 설정 , 사용자 권한 요구
### 2021-05-14
+ datetime picker 를 이용하여 알람 설정 완료
+ 현재 알람 페이지와 알람 수정 페이지가 같은 곳에 위치 이에 따라 보이는 데이터만 존재하고 수정 여부를 묻는 것을 만들지 고민중
......
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../shared/colors.dart';
import 'package:rxdart/subjects.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_application_1/src/screens/SettingPage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_application_1/src/screens/SettingPage.dart';
import 'package:flutter_application_1/src/screens/SettingPage/customTimepicker.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
......@@ -41,9 +40,17 @@ class Alarm extends StatefulWidget {
class _AlarmnState extends State<Alarm> {
FlutterLocalNotificationsPlugin fltrNotification;
List<Widget> alarmList = [];
List<dynamic> weekdays = [];
List<String> times = [];
List<int> timesHours = [];
List<int> timesMinutes = [];
List<dynamic> saveIndex = [];
List<dynamic> isSwitched = [];
List<bool> _weekday = [false, false, false, false, false, false, false];
void initState() {
super.initState();
main();
}
......@@ -84,6 +91,44 @@ class _AlarmnState extends State<Alarm> {
);
}
void insertAlarm() {
setState(() {
weekdays.add([false, false, false, false, false, false, false]);
times.add(' ');
timesHours.add(0);
timesMinutes.add(0);
isSwitched.add(false);
var length = saveIndex.length;
if (saveIndex.length == 0) {
saveIndex.add(1);
} else {
saveIndex.add(saveIndex[length - 1] + 1);
}
length = saveIndex.length;
/*
_prefs.setString('alarmList', weekdays.toString());
for (var i = 0; i < times.length; i++) {
_prefs.setString('time' + (saveIndex[i]).toString(),
'${timesHours[i]}:${timesMinutes[i]}');
}
_prefs.setString('timeIndex', saveIndex.toString());
_prefs.setString('toggle', isSwitched.toString());
*/
print(saveIndex);
});
}
void rerendering() {
print(weekdays);
print(times);
print(timesHours);
print(timesMinutes);
setState(() {});
}
void _configureDidReceiveLocalNotificationSubject() {
didReceiveLocalNotificationSubject.stream
.listen((ReceivedNotification receivedNotification) async {
......@@ -189,79 +234,406 @@ class _AlarmnState extends State<Alarm> {
],
),
),
body: FlatButton(
height: size.height * 0.07,
onPressed: () {
_showDailyAtTime(1, 2);
},
child: Text(
'알람 설정',
textScaleFactor: 1.0,
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontFamily: 'Noto',
fontWeight: FontWeight.bold),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 180,
height: 80,
padding: const EdgeInsets.all(20.0),
child: RaisedButton(
onPressed: () async {
insertAlarm();
},
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
side: BorderSide(color: Colors.blue)),
color: Color(0xff1674f6),
child: Text(
'알람 추가',
textScaleFactor: 1.0,
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
),
],
),
for (var i = 0; i < weekdays.length; i++)
inAlarmData(
context,
weekdays,
weekdays[i],
_showWeeklyAtDayAndTime,
times[i],
timesHours[i],
timesMinutes[i],
i + 1,
rerendering,
size,
)
],
),
),
color: Color(0xff8E97FD),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
),
),
);
}
Future<void> _cancelNotification() async {
await flutterLocalNotificationsPlugin.cancel(0);
}
Future<void> _showTimeoutNotification() async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'silent channel id',
'silent channel name',
'silent channel description',
timeoutAfter: 3000,
styleInformation: DefaultStyleInformation(true, true));
var iOSPlatformChannelSpecifics =
IOSNotificationDetails(presentSound: false);
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(0, 'timeout notification',
'Times out after 3 seconds', platformChannelSpecifics);
}
Widget inAlarmData(
BuildContext context,
var allweekddata,
var weekdayArray,
var activeFunctions,
var timeString,
var timeHour,
var timesMinite,
var index,
var rerendering,
Size size,
) {
SharedPreferences _prefs;
var savetimeStrings;
var setDaysString = ['월', '화', '수', '목', '금', '토', '일'];
return Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 20),
decoration: BoxDecoration(
border: Border.all(
color: Color(0xffd0d0d0),
),
borderRadius: BorderRadius.all(Radius.circular(5)),
),
child: Column(
children: <Widget>[
Container(
alignment: Alignment.center,
width: size.width,
height: 50.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (var i = 0; i < weekdayArray.length; i++)
GestureDetector(
onTap: () async {
_prefs = await SharedPreferences.getInstance();
if (weekdayArray[i] == false) {
weekdayArray[i] = true;
} else {
weekdayArray[i] = false;
}
_prefs.setString(
'alarmList', allweekddata.toString());
rerendering();
},
child: Container(
margin: EdgeInsets.fromLTRB(15, 0, 0, 0),
width: size.width * 0.09,
child: Text(
setDaysString[i],
style: TextStyle(
color: weekdayArray[i] == false
? Colors.teal
: Colors.red,
fontWeight: FontWeight.bold,
fontSize: 20.0),
)),
),
],
)
],
),
color: Colors.white,
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
elevation: 4.0,
onPressed: () async {
_prefs = await SharedPreferences.getInstance();
var abc = await DatePicker.showPicker(
context,
theme: DatePickerTheme(
containerHeight: 210.0,
),
showTitleActions: true,
onConfirm: (time) {
print('confirm $time');
// realTime = new DateTime(time.hour, time.minute);
timeHour = time.hour;
timesMinite = time.minute;
savetimeStrings = '${time.hour}:${time.minute}';
var minutString;
if (timesMinite.toString().length == 1) {
minutString = '0' + timesMinite.toString();
} else {
minutString = timesMinite.toString();
}
if (timeHour - 12 < 0) {
timeString = '오전 ${time.hour}:' + minutString;
} else {
if (timeHour == 12) {
timeString = '오후 ${time.hour}:' + minutString;
} else {
timeString = '오후 ${time.hour - 12}:' + minutString;
}
}
},
pickerModel: CustomPicker(
currentTime: DateTime.now(), locale: LocaleType.ko),
);
Future<void> _cancelAllNotifications() async {
await flutterLocalNotificationsPlugin.cancelAll();
}
times[index - 1] = timeString;
timesHours[index - 1] = timeHour;
timesMinutes[index - 1] = timesMinite;
/// 매일 지정된 시간에 Alarm 을 트는 Function
Future<void> _showDailyAtTime(int a, int b) async {
var time = Time(11, 24, 0);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'repeatDailyAtTime channel id',
'repeatDailyAtTime channel name',
'repeatDailyAtTime description');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.showDailyAtTime(
1,
'알람 시간 알림 ',
'설정하신 시간인 ${_toTwoDigitString(time.hour)}${_toTwoDigitString(time.minute)}분입니다.',
time,
platformChannelSpecifics);
_prefs.setString('time' + (saveIndex[index - 1]).toString(),
savetimeStrings);
var pendingNotificationRequests =
await flutterLocalNotificationsPlugin.pendingNotificationRequests();
print(savetimeStrings);
print(pendingNotificationRequests.toList());
setState(() {
savetimeStrings = savetimeStrings;
});
// rerendering();
},
child: Container(
alignment: Alignment.center,
height: 50.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.access_time,
size: 18.0,
color: Colors.teal,
),
Text(
" " + timeString,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
],
),
)
],
),
],
),
),
color: Colors.white,
),
Container(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white),
child: Container(
alignment: Alignment.center,
height: 50.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"알람 설정",
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
Switch(
value: isSwitched[index - 1],
onChanged: (value) async {
print(savetimeStrings);
if (value == true) {
_prefs = await SharedPreferences.getInstance();
int count = 1;
bool allDayFalse = true;
for (var i = 0; i < weekdayArray.length; i++) {
if (weekdayArray[i] == true) {
await activeFunctions(timeHour, timesMinite,
i + 1, index * 10, count);
count++;
allDayFalse = false;
}
}
if (allDayFalse == true) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text('요일 선택 오류'),
content:
new Text('선택된 요일이 없습니다. 요일을 선택해주세요.'),
actions: <Widget>[
new FlatButton(
child: new Text('닫기'),
onPressed: () {
Navigator.of(context).pop();
})
],
);
});
} else if (_prefs.getString('time' +
(saveIndex[index - 1]).toString()) ==
null) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text('시간 설정 오류'),
content:
new Text('설정된 시간이 없습니다. 시간을 설정해주세요.'),
actions: <Widget>[
new FlatButton(
child: new Text('닫기'),
onPressed: () {
Navigator.of(context).pop();
})
],
);
});
} else {
setState(() {
print(value);
isSwitched[index - 1] = value;
_prefs.setString(
'alarmList', allweekddata.toString());
// _prefs.setString(
// 'time' + saveIndex[index - 1].toString(),
// savetimeStrings);
_prefs.setString(
'timeIndex', saveIndex.toString());
_prefs.setString(
'toggle', isSwitched.toString());
print('time' + index.toString());
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text('알람'),
content: new Text('알람 설정을 완료 하였습니다.'),
actions: <Widget>[
new FlatButton(
child: new Text('확인'),
onPressed: () {
Navigator.of(context).pop();
})
],
);
});
});
}
} else {
_prefs = await SharedPreferences.getInstance();
int count = 1;
for (var i = 0; i < weekdayArray.length; i++) {
if (weekdayArray[i] == true) {
await flutterLocalNotificationsPlugin
.cancel((index * 10) + count);
count++;
}
}
setState(() {
isSwitched[index - 1] = value;
_prefs.setString('toggle', isSwitched.toString());
});
}
}),
GestureDetector(
onTap: () async {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text('알람 삭제'),
content: new Text('선택한 알람을 삭제하시겠습니까?'),
actions: <Widget>[
new FlatButton(
child: new Text('취소'),
onPressed: () {
Navigator.of(context).pop();
}),
new FlatButton(
child: new Text('삭제'),
onPressed: () async {
_prefs = await SharedPreferences
.getInstance();
int count = 1;
for (var i = 0;
i < weekdayArray.length;
i++) {
if (weekdayArray[i] == true) {
await flutterLocalNotificationsPlugin
.cancel((index * 10) + count);
count++;
}
}
print(saveIndex);
allweekddata.removeAt(index - 1);
_prefs.remove('time' +
saveIndex[index - 1].toString());
times.removeAt(index - 1);
saveIndex.removeAt(index - 1);
isSwitched.removeAt(index - 1);
_prefs.setString('alarmList',
allweekddata.toString());
_prefs.setString('timeIndex',
saveIndex.toString());
_prefs.setString(
'toggle', isSwitched.toString());
rerendering();
Navigator.of(context).pop();
})
],
);
});
},
child: Icon(
Icons.close,
))
],
),
),
),
],
));
}
/// weekday 가 1부터 7순으로 일 월 화 수 목 금 토 일 순서로 구성이 되어 있음 이에 따라 설정한 Weekday time 에 학습 알람을 뛰어주는 역할을 해주는 함수
Future<void> _showWeeklyAtDayAndTime(
int a, int b, int weekday, int index, int idindex) async {
print(index + idindex);
Day setDay;
if (weekday == 1) {
......@@ -279,6 +651,7 @@ class _AlarmnState extends State<Alarm> {
} else if (weekday == 7) {
setDay = Day.Sunday;
}
print('dd');
var time = Time(a, b, 0);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
......
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
class CustomPicker extends CommonPickerModel {
var indexs;
String digits(int value, int length) {
return '$value'.padLeft(length, "0");
}
CustomPicker({DateTime currentTime, LocaleType locale})
: super(locale: LocaleType.ko) {
this.currentTime = currentTime ?? DateTime.now();
var _dayPeriod = 0;
this.setLeftIndex(this.currentTime.hour);
this.setMiddleIndex(this.currentTime.minute);
this.setRightIndex(_dayPeriod);
_fillRightList();
}
@override
String leftStringAtIndex(int index) {
if (index >= 1 && index < 13) {
return this.digits(index, 2);
} else {
return null;
}
}
@override
String middleStringAtIndex(int index) {
if (index >= 0 && index < 60) {
return this.digits(index, 2);
} else {
return null;
}
}
@override
String rightStringAtIndex(int index) {
if (index == 0) {
return 'AM';
} else if (index == 1) {
return 'PM';
}
return null;
}
void _fillRightList() {
this.rightList = List.generate(2, (int index) {
return '$index';
});
}
@override
void setRightIndex(int index) {
super.setRightIndex(index);
indexs = index;
_fillRightList();
}
@override
String leftDivider() {
return ":";
}
@override
String rightDivider() {
return " ";
}
@override
List<int> layoutProportions() {
return [1, 1, 1];
}
@override
DateTime finalTime() {
var leftindex;
print(indexs);
if (indexs == 1) {
if(this.currentLeftIndex() == 12){
leftindex = 12;
} else {
leftindex = this.currentLeftIndex() + 12;
}
} else if (indexs == 0) {
if(this.currentLeftIndex() == 12){
leftindex = 0;
} else {
leftindex = this.currentLeftIndex();
}
}
return currentTime.isUtc
? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
leftindex, this.currentMiddleIndex(), this.currentRightIndex())
: DateTime(currentTime.year, currentTime.month, currentTime.day,
leftindex, this.currentMiddleIndex(), this.currentRightIndex());
}
}
......@@ -50,6 +50,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.1"
flutter:
dependency: "direct main"
description: flutter
......@@ -88,8 +102,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
intl:
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
intl:
dependency: "direct main"
description:
name: intl
url: "https://pub.dartlang.org"
......@@ -144,6 +163,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+2"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+3"
pedantic:
dependency: transitive
description:
......@@ -165,6 +205,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.13"
rxdart:
dependency: "direct main"
description:
......@@ -172,6 +219,48 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.23.1"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.12+4"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.2+4"
shared_preferences_macos:
dependency: transitive
description:
name: shared_preferences_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+11"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2+7"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.2+3"
sky_engine:
dependency: transitive
description: flutter
......@@ -240,6 +329,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.4+1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
sdks:
dart: ">=2.10.0-110 <2.11.0"
flutter: ">=1.12.13+hotfix.5"
flutter: ">=1.12.13+hotfix.5 <2.0.0"
......
......@@ -31,6 +31,8 @@ dependencies:
rxdart: ^0.23.1
flutter_datetime_picker: ^1.3.4
timezone: ^0.6.0
intl : ^0.16.1
shared_preferences: ^0.5.6+1
dev_dependencies:
flutter_test:
......