Roxx
Roxx

Reputation: 3986

Flutter: show notification on lock screen

First of all i have seen similar question on SO. Show notifications in lock screen by flutter But it is only giving plugin references which I am already using. Issue I want to show notification on the lock screen. I have already tried visibility: NotificationVisibility.public, but not sure why notifications are not showing on lock screen.

I am testing it on the physical device. On my device, other apps are sending notifications like whatsapp.

Here is my code.

FlutterLocalNotificationsPlugin notificationsPlugin =
    FlutterLocalNotificationsPlugin();

//Function to handle Notification data in background.
Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) async {
  print("FCM backgroundMessageHandler $message");
  showNotification(DataNotification.fromPushMessage(message['data']));
  return Future<void>.value();
}

//Function to handle Notification Click.
Future<void> onSelectNotification(String payload) {
  print("FCM onSelectNotification");
  return Future<void>.value();
}

//Function to Parse and Show Notification when app is in foreground
Future<dynamic> onMessage(Map<String, dynamic> message) {
  print("FCM onMessage $message");
  print(message['data']['title']);
  showNotification(DataNotification.fromPushMessage(message['data']));

  return Future<void>.value();
}

//Function to Handle notification click if app is in background
Future<dynamic> onResume(Map<String, dynamic> message) {
  print("FCM onResume $message");
 return Future<void>.value();
}

//Function to Handle notification click if app is not in foreground neither in background
Future<dynamic> onLaunch(Map<String, dynamic> message) {
  print("FCM onLaunch $message");
  return Future<void>.value();
}

void showNotification(DataNotification notification) async {
  final AndroidNotificationDetails androidPlatformChannelSpecifics =
      await getAndroidNotificationDetails(notification);

  final NotificationDetails platformChannelSpecifics =
      NotificationDetails(android: androidPlatformChannelSpecifics);

  await notificationsPlugin.show(
    0,
    notification.title,
    notification.body,
    platformChannelSpecifics,
  );
}

Future<AndroidNotificationDetails> getAndroidNotificationDetails(
    DataNotification notification) async {
  switch (notification.notificationType) {
    case NotificationType.NEW_INVITATION:
    case NotificationType.NEW_MEMBERSHIP:
    case NotificationType.NEW_ADMIN_ROLE:
    case NotificationType.MEMBERSHIP_BLOCKED:
    case NotificationType.MEMBERSHIP_REMOVED:
    case NotificationType.NEW_MEMBERSHIP_REQUEST:
      return AndroidNotificationDetails(
        'organization',
        'Organization management',
        'Notifications regarding your organizations and memberships.',
        importance: Importance.max,
        priority: Priority.high,
        showWhen: false,
        playSound: true,
        ledColor: Colors.redAccent,
        color: Colors.amber,
        category: "Organization",
        icon: '@mipmap/ic_launcher',
        visibility: NotificationVisibility.public,
        largeIcon: DrawableResourceAndroidBitmap('@mipmap/ic_launcher'),
        styleInformation: await getBigPictureStyle(notification),
        //sound: RawResourceAndroidNotificationSound('slow_spring_board')
      );
    case NotificationType.NONE:
    default:
      return AndroidNotificationDetails(
        'general', 'General notifications',
        'General notifications that are not sorted to any specific topics.',
        importance: Importance.max,
        priority: Priority.high,
        showWhen: false,
        category: "General",
        playSound: true,
        ledColor: Colors.redAccent,
        color: Colors.amber,
        icon: '@mipmap/ic_launcher',
        visibility: NotificationVisibility.public,
        largeIcon: DrawableResourceAndroidBitmap('@mipmap/ic_launcher'),
        styleInformation: await getBigPictureStyle(notification),
        // sound: RawResourceAndroidNotificationSound('slow_spring_board')
      );
  }
}

Future<BigPictureStyleInformation> getBigPictureStyle(
    DataNotification notification) async {
  if (notification.imageUrl != null) {
    print("downloading");
    final String bigPicturePath =
        await _downloadAndSaveFile(notification.imageUrl, 'bigPicture');

    return BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
        hideExpandedLargeIcon: true,
        contentTitle: notification.title,
        htmlFormatContentTitle: false,
        summaryText: notification.body,
        htmlFormatSummaryText: false);
  } else {
    print("NOT downloading");
    return null;
  }
}

Future<String> _downloadAndSaveFile(String url, String fileName) async {
  final Directory directory = await getApplicationDocumentsDirectory();
  final String filePath = '${directory.path}/$fileName';
  final http.Response response = await http.get(url);
  final File file = File(filePath);
  await file.writeAsBytes(response.bodyBytes);
  return filePath;
}

class NotificationService {
  FirebaseMessaging _fcm = FirebaseMessaging();

  void init() async {
    // Get.to(BookingQRScan());
    final AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    final IOSInitializationSettings initializationSettingsIOS =
        IOSInitializationSettings();

    final InitializationSettings initializationSettings =
        InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );

    await notificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (value) => onSelectNotification(value));

    _fcm.configure(
      onMessage: onMessage,
      onBackgroundMessage: backgroundMessageHandler,
      onLaunch: onLaunch,
      onResume: onResume,
    );
  }
}

Upvotes: 1

Views: 8613

Answers (2)

Mohamed Ayman
Mohamed Ayman

Reputation: 23

There are two solutions for this issue. First one has been mention up.

Second, is to edit AndroidManifest.xml and put this code android:showWhenLocked="true" android:turnScreenOn="true" into .MainActivity so it be like <activity android:name=".MainActivity" <<Some Additional Setting That you want>> android:showWhenLocked="true" android:turnScreenOn="true">

This worked for me without asking the user to enable specific settings

I got it from flutter_local_notifications

Upvotes: 2

Roxx
Roxx

Reputation: 3986

I searched about this topic and found that we can't set the settings programmatically. User needs to enable this settings.

Like below screenshot. enter image description here

I tried to redirect the user to direct notification settings page but didn't found any service.

So, I dig more and found one plugin app_settings.

https://pub.dev/packages/app_settings

This will directly open the notification settings for the app.

RaisedButton(
                onPressed: () {
                  // AppSettings.openLocationSettings();
                  AppSettings.openNotificationSettings();
                  //  openWIFISettings();
                },

Upvotes: 3

Related Questions