Я делаю календарное приложение, где вы можете запланировать дни. Одна повестка дня работает для меня, но я не могу запланировать больше. Я пробовал несколько вещей, но я не вижу никаких результатов. Я получаю ошибку «Планирование ошибок. Проверьте разрешения». Однако разрешения в порядке. Здесь я оставляю вам кусок кода, где я подозреваю, что ошибка может быть. Извините, если все на испанском. < /P>
Future _loadAgendas() async {
try {
final loaded = await AgendaStorage.loadAgendaItems();
if (mounted) {
setState(() {
_agendas = loaded;
});
}
} catch (e) {
// Manejo silencioso del error
}
}
int _getUniqueId() {
int candidateId = DateTime.now().millisecond;
while (_agendas.any((item) => item.id == candidateId)) {
candidateId++;
}
return candidateId;
}
void _pickTimeAndSchedule() async {
if (_isLoading) return;
if (!NotificationService.isInitialized) {
_showErrorMessage('Servicio de notificaciones no disponible');
return;
}
final DateTime now = DateTime.now();
final DateTime today = DateTime(now.year, now.month, now.day);
final DateTime selectedDate = DateTime(
_selectedDay.year,
_selectedDay.month,
_selectedDay.day,
);
if (selectedDate.isBefore(today)) {
_showErrorMessage('No puedes agendar notificaciones en días pasados.');
return;
}
final motivo = await _showReasonDialog();
if (motivo == null || motivo.isEmpty) return;
final time = await _showTimePicker(selectedDate, today);
if (time == null) return;
final scheduledDate = DateTime(
_selectedDay.year,
_selectedDay.month,
_selectedDay.day,
time.hour,
time.minute,
);
if (scheduledDate.isBefore(now.add(const Duration(minutes: 1)))) {
_showErrorMessage(
'La fecha y hora debe ser al menos 1 minuto en el futuro.',
);
return;
}
setState(() {
_isLoading = true;
});
try {
await _scheduleNotificationAndSave(scheduledDate, motivo);
} catch (e) {
_showErrorMessage('Error inesperado al crear la agenda.');
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
}
Future _showReasonDialog() async {
final TextEditingController motivoController = TextEditingController();
return await showDialog(
context: context,
barrierDismissible: false,
builder:
(context) => Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.blue.shade50, Colors.white],
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.blue.shade100,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.edit_note,
color: Colors.blue.shade700,
),
),
const SizedBox(width: 12),
const Text(
'Motivo del recordatorio',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: 20),
TextField(
controller: motivoController,
decoration: InputDecoration(
hintText: 'Ej: Cita médica, Tomar medicamento...',
filled: true,
fillColor: Colors.grey.shade50,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.blue.shade300,
width: 2,
),
),
),
autofocus: true,
maxLength: 100,
textCapitalization: TextCapitalization.sentences,
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context, null),
child: Text(
'Cancelar',
style: TextStyle(color: Colors.grey.shade600),
),
),
const SizedBox(width: 12),
ElevatedButton(
onPressed: () {
final text = motivoController.text.trim();
if (text.isNotEmpty) {
Navigator.pop(context, text);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue.shade600,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
child: const Text('Aceptar'),
),
],
),
],
),
),
),
);
}
Future _showTimePicker(
DateTime selectedDate,
DateTime today,
) async {
TimeOfDay initialTime;
if (selectedDate.isAtSameMomentAs(today)) {
final currentTime = TimeOfDay.now();
final nextHour = currentTime.hour + 1;
initialTime = TimeOfDay(
hour: nextHour >= 24 ? 0 : nextHour,
minute: currentTime.minute,
);
} else {
initialTime = const TimeOfDay(hour: 9, minute: 0);
}
return await showTimePicker(
context: context,
initialTime: initialTime,
helpText: 'Selecciona la hora del recordatorio',
confirmText: 'Aceptar',
cancelText: 'Cancelar',
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
timePickerTheme: TimePickerThemeData(
backgroundColor: Colors.white,
dialBackgroundColor: Colors.blue.shade50,
dialHandColor: Colors.blue.shade600,
hourMinuteTextColor: Colors.blue.shade800,
dayPeriodTextColor: Colors.blue.shade600,
),
),
child: child!,
);
},
);
}
Future _scheduleNotificationAndSave(
DateTime scheduledDate,
String motivo,
) async {
final int newId = _getUniqueId();
final now = DateTime.now();
if (scheduledDate.isBefore(now.add(const Duration(minutes: 1)))) {
_showErrorMessage('La fecha debe ser al menos 1 minuto en el futuro.');
return;
}
bool scheduled = await NotificationService.scheduleNotification(
scheduledDate,
id: newId,
reason: motivo,
);
if (!scheduled) {
scheduled = await NotificationService.scheduleNotificationAlternative(
scheduledDate,
id: newId,
reason: motivo,
);
}
if (!scheduled) {
_showErrorMessage('Error al programar. Verifica permisos.');
return;
}
final newItem = AgendaItem(
id: newId,
dateTime: scheduledDate,
reason: motivo,
);
try {
final success = await AgendaStorage.saveAgendaItem(newItem);
if (!success) throw Exception('Falló al guardar en almacenamiento');
setState(() => _agendas.add(newItem));
_showSuccessMessage(
'Agendado para: ${DateFormat.yMd().add_jm().format(scheduledDate)}',
);
} catch (e) {
await NotificationService.cancelNotification(newId);
_showErrorMessage('Error al guardar: ${e.toString()}');
}
}
< /code>
Я попытался использовать Millisecondssinceepoch или любого с тех пор, с тех пор я не смог что -то запланировать напрямую. < /p>
millisecondsSinceEpoch
Подробнее здесь: https://stackoverflow.com/questions/796 ... e-more-day
Мое приложение по планированию трепетания может запланировать день, но тогда я не могу запланировать больше дней. Как я ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение