224 lines
7.1 KiB
Dart
224 lines
7.1 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'dart:ui';
|
|
|
|
//import 'package:apkcoba/bottom_navigation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:firebase_core/firebase_core.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
import 'package:flutter_background_service/flutter_background_service.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:firebase_database/firebase_database.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
// Import halaman
|
|
import 'history_page.dart';
|
|
import 'notifikasi_page.dart';
|
|
import 'profile_page.dart';
|
|
import 'splash_screen.dart';
|
|
import 'login_screen.dart';
|
|
import 'signup_screen.dart';
|
|
import 'home_screen.dart';
|
|
import 'firebase_options.dart';
|
|
import 'jadwal_kotak_obat1_screen.dart';
|
|
import 'atur_jadwal1_screen.dart';
|
|
import 'jadwal_kotak_obat2_screen.dart';
|
|
import 'atur_jadwal2_screen.dart';
|
|
import 'notifikasi_service.dart';
|
|
import 'bottom_navigation.dart';
|
|
// import 'background_service.dart';
|
|
|
|
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
// Firebase initialization untuk Web dan Non-Web
|
|
if (kIsWeb) {
|
|
await Firebase.initializeApp(
|
|
options: const FirebaseOptions(
|
|
apiKey: "AIzaSyAUVen3yiSUrNJw7HnRif0_IBmUdeStY0c",
|
|
appId: "1:531750565610:web:5acfbccca5e41ee8404993",
|
|
messagingSenderId: "531750565610",
|
|
projectId: "coba-smartmedibox",
|
|
databaseURL: "https://coba-smartmedibox-default-rtdb.firebaseio.com",
|
|
),
|
|
);
|
|
} else {
|
|
await Firebase.initializeApp(
|
|
options: DefaultFirebaseOptions.currentPlatform,
|
|
);
|
|
}
|
|
await initializeService();
|
|
//await NotifikasiService.init(); // Tambahkan ini supaya plugin notifikasi lokal siap
|
|
//NotifikasiService.listenToAllNotifikasi();
|
|
|
|
//await initializeNotifications();
|
|
//await initializeService();
|
|
|
|
runApp(const MyApp());
|
|
}
|
|
|
|
Future<void> initializeService() async {
|
|
final service = FlutterBackgroundService();
|
|
|
|
/// OPTIONAL, using custom notification channel id
|
|
const AndroidNotificationChannel channel = AndroidNotificationChannel(
|
|
'my_foreground', // id
|
|
'MY FOREGROUND SERVICE', // title
|
|
description:
|
|
'This channel is used for important notifications.', // description
|
|
importance: Importance.low, // importance must be at low or higher level
|
|
);
|
|
|
|
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
|
FlutterLocalNotificationsPlugin();
|
|
|
|
const AndroidInitializationSettings initializationSettingsAndroid =
|
|
AndroidInitializationSettings('@mipmap/ic_launcher'); // TANPA .png
|
|
|
|
const InitializationSettings initializationSettings = InitializationSettings(
|
|
android: initializationSettingsAndroid,
|
|
);
|
|
|
|
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
|
|
|
await flutterLocalNotificationsPlugin
|
|
.resolvePlatformSpecificImplementation<
|
|
AndroidFlutterLocalNotificationsPlugin
|
|
>()
|
|
?.createNotificationChannel(channel);
|
|
|
|
await service.configure(
|
|
androidConfiguration: AndroidConfiguration(
|
|
// this will be executed when app is in foreground or background in separated isolate
|
|
onStart: onStart,
|
|
|
|
// auto start service
|
|
autoStart: true,
|
|
isForegroundMode: true,
|
|
|
|
notificationChannelId: 'my_foreground',
|
|
initialNotificationTitle: 'Smart Medicine Box',
|
|
initialNotificationContent: 'Medibox Sedang Berjalan',
|
|
foregroundServiceNotificationId: 888,
|
|
|
|
foregroundServiceTypes: [AndroidForegroundType.location],
|
|
),
|
|
iosConfiguration: IosConfiguration(
|
|
// auto start service
|
|
autoStart: true,
|
|
|
|
// this will be executed when app is in foreground in separated isolate
|
|
onForeground: onStart,
|
|
|
|
// you have to enable background fetch capability on xcode project
|
|
onBackground: onIosBackground,
|
|
),
|
|
);
|
|
}
|
|
|
|
// to ensure this is executed
|
|
// run app from xcode, then from xcode menu, select Simulate Background Fetch
|
|
|
|
@pragma('vm:entry-point')
|
|
Future<bool> onIosBackground(ServiceInstance service) async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
DartPluginRegistrant.ensureInitialized();
|
|
|
|
SharedPreferences preferences = await SharedPreferences.getInstance();
|
|
await preferences.reload();
|
|
final log = preferences.getStringList('log') ?? <String>[];
|
|
log.add(DateTime.now().toIso8601String());
|
|
await preferences.setStringList('log', log);
|
|
|
|
return true;
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
void onStart(ServiceInstance service) async {
|
|
DartPluginRegistrant.ensureInitialized();
|
|
await Firebase.initializeApp();
|
|
print('✅ Firebase initialized');
|
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
String? userId;
|
|
int retry = 0;
|
|
|
|
while ((userId = prefs.getString('userId')) == null && retry < 30) {
|
|
print("⏳ Menunggu userId tersimpan... [percobaan ke-$retry]");
|
|
await Future.delayed(Duration(seconds: 2));
|
|
await prefs.reload();
|
|
retry++;
|
|
}
|
|
|
|
if (userId == null) {
|
|
print(
|
|
"❌ Gagal mendapatkan userId setelah beberapa percobaan. onStart dihentikan.",
|
|
);
|
|
return;
|
|
}
|
|
|
|
print("✅ userId ditemukan: $userId");
|
|
|
|
await NotifikasiService.init();
|
|
|
|
if (userId != null) {
|
|
print('✅ Memulai listener notifikasi...');
|
|
await NotifikasiService.listenToAllNotifikasiWithUserId(userId);
|
|
syncTimestampIfAuthorizedWithListener(userId);
|
|
}
|
|
|
|
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
|
FlutterLocalNotificationsPlugin();
|
|
|
|
if (service is AndroidServiceInstance) {
|
|
service.on('setAsForeground').listen((event) {
|
|
service.setAsForegroundService();
|
|
});
|
|
|
|
service.on('setAsBackground').listen((event) {
|
|
service.setAsBackgroundService();
|
|
});
|
|
}
|
|
|
|
service.on('stopService').listen((event) {
|
|
service.stopSelf();
|
|
});
|
|
}
|
|
|
|
class MyApp extends StatelessWidget {
|
|
const MyApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
navigatorKey: navigatorKey,
|
|
title: 'SmartMediBox',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: ThemeData(
|
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
|
|
useMaterial3: true,
|
|
),
|
|
home: const SplashScreen(),
|
|
routes: {
|
|
'/login': (context) => const LoginScreen(),
|
|
'/signUp': (context) => const SignUpScreen(),
|
|
'/home': (context) => const MainNavigation(currentIndex: 0),
|
|
'/home2': (context) => HomeScreen(username: '', onSignOut: () {}),
|
|
'/jadwalKotakObat1': (context) => const JadwalKotakObat1Screen(),
|
|
'/aturJadwal1': (context) => const AturJadwal1Screen(),
|
|
'/jadwalKotakObat2': (context) => const JadwalKotakObat2Screen(),
|
|
'/aturJadwal2': (context) => const AturJadwal2Screen(),
|
|
'/historyPage': (context) => const HistoryPage(),
|
|
'/notifikasiPage': (context) => const NotifikasiPage(),
|
|
'/profilePage': (context) => const ProfilePage(),
|
|
},
|
|
);
|
|
}
|
|
}
|