skip to Main Content

The problem is in detail

I use the Awesome_notifications package. The notifications work in a good way from time to time, but no sometimes they only work when the application is opened. The Awesome_notifications package says that this is due to the power saving mode of the devices.
See the picture:[1]: https://i.sstatic.net/4ajWVQ9L.jpg

Note: I schedule notifications according to the time specified by the user
2:How to use
background_fetch
with
Awesome_notifications

// code

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:device_preview/device_preview.dart';
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:showcaseview/showcaseview.dart';
import 'package:upgrader/upgrader.dart';
import 'package:background_fetch/background_fetch.dart';

// [Android-only] This "Headless Task" is run when the Android app is terminated with `enableHeadless: true`
// Be sure to annotate your callback function to avoid issues in release mode on Flutter >= 3.3.0
@pragma('vm:entry-point')
void backgroundFetchHeadlessTask(HeadlessTask task) async {
  String taskId = task.taskId;
  bool isTimeout = task.timeout;
  if (isTimeout) {
    // This task has exceeded its allowed running-time.
    // You must stop what you're doing and immediately .finish(taskId)
    print("[BackgroundFetch] Headless task timed-out: $taskId");
    BackgroundFetch.finish(taskId);
    return;
  }
  print('[BackgroundFetch] Headless event received.');
  // Do your work here...
  //Notification
  notfi();
  BackgroundFetch.finish(taskId);
}

TimeOfDay _timeOfDay =  const TimeOfDay(hour:5, minute: 0);



void main()async{
  WidgetsFlutterBinding.ensureInitialized();

  await Permission.notification.isDenied.then(
          (value) {

        if (value) {
          Permission.notification.request();
        }

      }
  );


  AwesomeNotifications().initialize(
    null,
    [
      NotificationChannel(

        channelKey: 'basic_keyadh',
        channelName: 'chnneladhs',
        channelDescription: 'fghjks',
        importance: NotificationImportance.Max,
        //channelShowBadge:true,
        defaultRingtoneType: DefaultRingtoneType.Notification,
        onlyAlertOnce: true,


      ),


    ],

    channelGroups: [
      NotificationChannelGroup(

          channelGroupName: 'Basic group',
          channelGroupKey: 'basic_channel_group'

      ),
    ],
    debug: true,
  );
 // await NotificationService.initializeNotifications();
  

  runApp(DevicePreview(enabled: true,builder: (context) =>  const MyApp23 (),


  ),
  );

BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);

}
class MyApp23 extends StatefulWidget {
  const MyApp23({super.key});

  @override
  State<MyApp23> createState() => _MyApp23State();


}

class _MyApp23State extends State<MyApp23> with WidgetsBindingObserver {




// Be sure to annotate your callback function to avoid issues in release mode on Flutter >= 3.3.0

  @override
  void initState() {
    super.initState();
    initPlatformState();


  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // Configure BackgroundFetch.
    int status = await BackgroundFetch.configure(BackgroundFetchConfig(
        minimumFetchInterval: 15,
        stopOnTerminate: false,
        enableHeadless: true,
        requiresBatteryNotLow: false,
        requiresCharging: false,
        requiresStorageNotLow: false,
        requiresDeviceIdle: false,
        requiredNetworkType: NetworkType.NONE
    ), (String taskId) async {  // <-- Event handler
      // This is the fetch-event callback.
      print("[BackgroundFetch] Event received $taskId");
      setState(() {

      });
      // IMPORTANT:  You must signal completion of your task or the OS can punish your app
      // for taking too long in the background.
      BackgroundFetch.finish(taskId);
    }, (String taskId) async {  // <-- Task timeout handler.
      // This task has exceeded its allowed running-time.  You must stop what you're doing and immediately .finish(taskId)
      print("[BackgroundFetch] TASK TIMEOUT taskId: $taskId");
      BackgroundFetch.finish(taskId);
    });
    print('[BackgroundFetch] configure success: $status');
    setState(() {

    });

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
  }

  @override
  void dispose(){

    WidgetsBinding.instance.removeObserver(this);
    super.dispose();


  }


  @override
  Widget build(BuildContext context) {


    //Set the fit size (Find your UI design, look at the dimensions of the device screen and fill it in,unit in dp)
    return ScreenUtilInit(
      //designSize: const Size(360, 690),
      minTextAdapt: true,
      splitScreenMode: true,

      // Use builder only if you need to use library outside ScreenUtilInit context
      builder: (_ , child) {
        return ShowCaseWidget(
          builder : (context) =>  MaterialApp(
            debugShowCheckedModeBanner: false,
            //title: 'First Method',
            // You can use the library anywhere in the app even in theme
            theme: ThemeData(
              primarySwatch: Colors.blue,
              textTheme: Typography.englishLike2018.apply(fontSizeFactor: 1.sp),
            ),
            home: UpgradeAlert(
                dialogStyle: UpgradeDialogStyle.cupertino,
                upgrader: Upgrader(
                  //  minAppVersion:"1.0.0",
                  debugLogging:true,
                  debugDisplayAlways:true,
                  languageCode:'ar',
                  messages: UpgraderMessages(
                    code: 'ar',
                  ),
                  // durationUntilAlertAgain: const Duration(days: 1),
                ),
                child: child),
          ),
        );
      },
      child:  const Demo(),
    );
  }

}


///Stings
class Demo extends StatefulWidget{
  const Demo({super.key});

  @override
  State<Demo> createState() => _DemoState();
}

class _DemoState extends State<Demo> with SingleTickerProviderStateMixin {

  @override
  void initState() {
    super.initState();

    getSavedData();
  }

  getSavedData() async {
    final pref = await SharedPreferences.getInstance();


    //appData.MyColor = Color(pref.getInt('MyColor')??Colors.white.value);
    //appData.col1= pref.getBool('col1') ??appData.col1;
    //appData.col2= pref.getBool('col2') ??appData.col2;
    // get the saved value from stored prefs
    // and make sure to do it inside `setState`
    // cannot use DateTime.parse because _timeOfDaybgm.toString() doesn't return a value
    // DateTime.parse can understand
    setState(() {
      int  ssavedHour = pref.getInt('_timeOfDay') ?? _timeOfDay.hour;
      int  ssavedMinute = pref.getInt('_timeOfDay2') ??_timeOfDay.minute;
      _timeOfDay = TimeOfDay(hour: ssavedHour, minute: ssavedMinute);

      //////////////////////////////////////////////////////////////////////////////////



    });
  }


  @override
  void dispose(){


    super.dispose();


  }



  @override
  Widget build(BuildContext context) {

   // notfi();


    return Scaffold(

      appBar: AppBar(


        automaticallyImplyLeading: false,

        centerTitle:true,

        backgroundColor:const Color.fromARGB(255, 241, 204, 100),
        scrolledUnderElevation: 0.0,
        title:const Text(

          "Demo",
          style: TextStyle(


            color:Colors.white,
            fontWeight: FontWeight.bold,
          )
          ,),

      ) ,
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        //mainAxisAlignment: MainAxisAlignment.center,
        children: [

          Center(
            child: TextButton(onPressed: () async {
              


              final TimeOfDay?timeOfDay = await showTimePicker(


                  context: context,
                  initialEntryMode: TimePickerEntryMode.dialOnly,

                  initialTime:_timeOfDay,

                  builder: (BuildContext context, Widget? child){

                    return Theme(
                      data: Theme.of(context).copyWith(

                          textTheme:   const TextTheme(
                            // ignore: deprecated_member_use
                            button:  TextStyle(

                              //fontSize:  BoodyTextSize(),

                            ),
                            // ignore: deprecated_member_use
                            subtitle1: TextStyle(


                            ),

                            // ignore: deprecated_member_use
                            bodyText2: TextStyle(

                              //fontSize: Titlesize(),
                              color:Color.fromARGB(255, 239, 158, 52),
                            ),

                          ),
                          colorScheme: const ColorScheme.light(
                            onBackground:Color.fromARGB(255, 253, 199, 126),
                            tertiaryContainer: Color.fromARGB(255, 253, 199, 126),
                            primary:Color.fromARGB(255, 253, 199, 126),
                          )),
                      child: child!,
                    ) ;
                  }

              );
              if (timeOfDay!= null) {
                setState(() {
                  _timeOfDay=timeOfDay;

                });
                // ignore: use_build_context_synchronously
                FocusScope.of(context).unfocus();
                final prefs = await SharedPreferences.getInstance();
                // changed setString to setInt, just makes it easier
                await prefs.setInt('_timeOfDay', _timeOfDay.hour);
                await prefs.setInt('_timeOfDay2', _timeOfDay.minute);
              }




            }, child: const Text("Schedule",style: TextStyle(color: Colors.red),)),
          )

        ],
      ) ,
    );
  }
}

//Notification
notfi() {

  AwesomeNotifications().createNotification(
    schedule:NotificationCalendar(
      //  allowWhileIdle:true,
      //  preciseAlarm: true,
      hour: _timeOfDay.hour,
      minute: _timeOfDay.minute,
      second: 0,
      repeats: true,

    ),
    /*  actionButtons: <NotificationActionButton>[
        NotificationActionButton(

          key: 'accept',
          label: 'قراه',
          color: const Color.fromARGB(183, 79, 34, 240),
        ),
        NotificationActionButton(
          key: 'reject',
          label: 'اغلاق ',
          color: const Color.fromARGB(183, 79, 34, 240),
        ),
      ],*/
    content: NotificationContent(

     // icon: 'resource://mipmap/shado',
      id:2,
      channelKey: 'basic_keyadh',
      title: 'He works',
      // body: '',


    ),
  );

}

I want to use the background_fetch package, but the problem is that I don’t know the method and where to put the code to fetch notifications. Is it inside the background call function?!
Thanks to everyone who helped me.

2

Answers


  1. Chosen as BEST ANSWER

    Notifications do not come at all when adding this code.

    And in main.dart initialize:

    await Notify.initializeNotification();
    //await Notify.initializeRemoteNotifications();
    

    Create Notify:

    import 'dart:math';
    import 'package:adhdhkar_muslim/virb_uli.dart';
    import 'package:awesome_notifications/awesome_notifications.dart';
    class Notify {
      static Future initializeNotification() async {
        AwesomeNotifications().requestPermissionToSendNotifications();
        AwesomeNotifications().initialize(
          null,
          [
            NotificationChannel(
    
          channelKey: 'basic_keyadhs',
          channelName: 'chnneladhs',
          channelDescription: 'fghjks',
          importance: NotificationImportance.Max,
          //channelShowBadge:true,
          defaultRingtoneType: DefaultRingtoneType.Notification,
          onlyAlertOnce: true,
    
    
        ),
          ],
           debug: true,
        );
      }
    
      static Future<bool> instantNotify(String title) async {
        final AwesomeNotifications awesomeNotifications = AwesomeNotifications();
        return await awesomeNotifications.createNotification(
          content: NotificationContent(
              icon: 'resource://mipmap/shado',
            id: Random().nextInt(100),
            title: title,
            body: "Notification that delivers instantly on trigger.",
            channelKey: 'basic_keyadhs',
          ),
        );
      }
    
      static Future<bool> scheduleNotification() async {
        final AwesomeNotifications awesomeNotifications = AwesomeNotifications();
        return await awesomeNotifications.createNotification(
          schedule:NotificationCalendar(
                   // allowWhileIdle:true,
                    //preciseAlarm: true,
                    hour: appData.timeOfDaydk.hour,
                    minute: appData.timeOfDaydk.minute,
                    second: 0,
                    repeats: true,
                   
                  ),
          content: NotificationContent(
            id: Random().nextInt(100),
            title: "Scheduled Notification",
            body: "So this notification will get triggered when it's 9 pm on my device and the date is December 9, 2021.",
            channelKey: 'basic_keyadh',
            wakeUpScreen: true,
            autoDismissible: false,
            category: NotificationCategory.Reminder,
          ),
        );
      }
    
      static Future<void> retrieveScheduledNotifications() async {
        final AwesomeNotifications awesomeNotifications = AwesomeNotifications();
        List<NotificationModel> scheduledNotifications = await awesomeNotifications.listScheduledNotifications();
        print(scheduledNotifications);
      }
    }
    

  2. You are making this implementation complex for yourself, Use: Awesome_notification, Awesome_notification_fcm

    And in main.dart initialize:

    await Notify.initializeNotification();
    await Notify.initializeRemoteNotifications();
    

    Create Notify:

    class Notify {
      static Future initializeNotification() async {
        AwesomeNotifications().requestPermissionToSendNotifications();
        AwesomeNotifications().initialize(
          null,
          [
            /// create channels
          ]
      }
    
      static Future<bool> instantNotify(String title) async {
        final AwesomeNotifications awesomeNotifications = AwesomeNotifications();
        return await awesomeNotifications.createNotification(
          content: NotificationContent(
            id: Random().nextInt(100),
            title: title,
            body: "Notification that delivers instantly on trigger.",
            channelKey: 'channel_key',
          ),
        );
      }
    
      static Future<bool> scheduleNotification() async {
        final AwesomeNotifications awesomeNotifications = AwesomeNotifications();
        return await awesomeNotifications.createNotification(
          schedule: NotificationInterval(interval: 10),
          content: NotificationContent(
            id: Random().nextInt(100),
            title: "Scheduled Notification",
            body: "So this notification will get triggered when it's 9 pm on my device and the date is December 9, 2021.",
            channelKey: 'channel_key_different',
            wakeUpScreen: true,
            autoDismissible: false,
            category: NotificationCategory.Reminder,
          ),
        );
      }
    
      static Future<void> retrieveScheduledNotifications() async {
        final AwesomeNotifications awesomeNotifications = AwesomeNotifications();
        List<NotificationModel> scheduledNotifications = await awesomeNotifications.listScheduledNotifications();
        print(scheduledNotifications);
      }
    
      ///  *********************************************
      ///     INITIALIZATION METHODS
      ///  *********************************************
    
      static Future<void> initializeRemoteNotifications() async {
        await Firebase.initializeApp();
        await AwesomeNotificationsFcm().initialize(
          onFcmSilentDataHandle: mySilentDataHandle,
          onFcmTokenHandle: myFcmTokenHandle,
          onNativeTokenHandle: myNativeTokenHandle,
          // This license key is necessary only to remove the watermark for
          // push notifications in release mode. To know more about it, please
          // visit http://awesome-notifications.carda.me#prices
          // licenseKeys: null,
          debug: true,
        );
      }
    
      ///  *********************************************
      ///     REMOTE NOTIFICATION EVENTS
      ///  *********************************************
    
      /// Use this method to execute on background when a silent data arrives
      /// (even while terminated)
      @pragma("vm:entry-point")
      static Future<void> mySilentDataHandle(FcmSilentData silentData) async {
        print('"SilentData": ${silentData.toString()}');
    
        if (silentData.createdLifeCycle != NotificationLifeCycle.Foreground) {
          print("bg");
        } else {
          print("FOREGROUND");
        }
    
        print("starting long task");
        await Future.delayed(const Duration(seconds: 4));
        final url = Uri.parse("http://google.com");
        final re = await http.get(url);
        print(re.body);
        print("long task done");
      }
    
      /// Use this method to detect when a new fcm token is received
      @pragma("vm:entry-point")
      static Future<void> myFcmTokenHandle(String token) async {
        debugPrint('FCM Token:"$token"');
      }
    
      /// Use this method to detect when a new native token is received
      @pragma("vm:entry-point")
      static Future<void> myNativeTokenHandle(String token) async {
        debugPrint('Native Token:"$token"');
      }
    
      // Request FCM token to Firebase
      Future<String> getFirebaseMessagingToken() async {
        showInAppMessage();
        String firebaseAppToken = '';
        if (await AwesomeNotificationsFcm().isFirebaseAvailable) {
          try {
            firebaseAppToken = await AwesomeNotificationsFcm().requestFirebaseAppToken();
            print(firebaseAppToken);
          } catch (exception) {
            debugPrint('$exception');
          }
        } else {
          debugPrint('Firebase is not available on this project');
        }
        return firebaseAppToken;
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search