mitchhymel / local_notifications

No longer in development -Flutter plugin for creating notifications
BSD 2-Clause "Simplified" License
108 stars 14 forks source link

Android Notifications not showing, iOS showing correctly #9

Closed rodydavis closed 6 years ago

rodydavis commented 6 years ago

`import 'package:camera/camera.dart'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; import 'package:image_picker/image_picker.dart'; import 'package:Unify_Mobile/globals.dart' as globals; import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:local_notifications/local_notifications.dart';

Future openCamera(BuildContext context, bool photo) async { cameras = await availableCameras(); if (photo) { //Picture Navigator.push( context, new MaterialPageRoute(builder: (context) => new MyHomePage()), ); } else { //Video } }

List cameras;

class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override _MyHomePageState createState() => new _MyHomePageState(); }

class _MyHomePageState extends State { Future _imageFile;

Image uploadImage(File file) { return new Image.file(file); }

onNotificationClick(String payload) { // // payload is "some payload" // LocalNotifications.removeNotification(0); print('Running in background and received payload: $payload'); }

void sendNotification(String title, String message, int id) async { await LocalNotifications.createNotification( title: title, content: message, id: id, onNotificationClick: new NotificationAction( actionText: "some action", // Note: only works for iOS callback: onNotificationClick, payload: "some payload")); }

@override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: const Text('Capture'), backgroundColor: Colors.white, actions: [ new IconButton( tooltip: 'Upload to Gallery', icon: new Icon( Icons.file_upload, ), onPressed: () { _imageFile == null ? globals.Utility.showAlertPopup(context, "Info", "Photo Required for Upload!", "") : sendNotification( "Upload Complete", "Image has finished processing.", 0); //True for Stock Camera }, ), ], ), body: new Center( child: new FutureBuilder( future: _imageFile, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.error == null) { return new Image.file(snapshot.data); } else if (snapshot.error != null) { return const Text('error picking video.'); } else { return const Text('You have not yet picked an video.'); } })), floatingActionButton: new FloatingActionButton( onPressed: () { setState(() { _imageFile = ImagePicker.pickImage(); }); }, tooltip: 'Pick Video', child: new Icon(Icons.add_a_photo), ), ); } } `

mitchhymel commented 6 years ago

I was able to set up a new flutter project, add local_notifications to my pubspec and use the library to create notifications on android (sdk 23 and 25), so I'm not sure where the issue is here.

A few thoughts:

rodydavis commented 6 years ago

Okay I will try that and update flutter. It may be a couple versions behind. I have never run the flutter clean command before and that could also be it. Thank you for the suggestions.

for reference I was testing on an iPhone 6s and Google Pixel with the latest operating systems.

on launch iOS requested for notifications but android never did. Is that as designed on android?

mitchhymel commented 6 years ago

Weird. I tested on a few AVDs as well as my own Pixel with the latest OS and haven't had any issues. Perhaps this indicates I need to add more/better logging to help debug these types of issues?

Regarding the iOS and Android differences.. Android uses an "opt-out" model for notifications: all apps by default have permissions to send notifications and the user has the ability to block notifications for a certain app.

iOS uses an "opt-in" model for notifications: all apps by default do not have permissions to send notifications and the app must explicitly ask the user for permission before being able to do so.

huextrat commented 6 years ago

Hi, I added the notification system on one of my apps and it works but on Android I don't have the vibration and the notification is not displayed. I have to check the notification center to see it. But I ask if the vibration is implemented or not yet?

I didn't check on iOS atm.

mitchhymel commented 6 years ago

@AppleEducate Did you mean that the notification doesn't show up even in the status bar or notification drawer? or that it doesn't show up on the screen when it is created (as a heads up notification)? (Also @huextrat ) On android, heads up notification behavior is not yet implemented. On iOS, the heads up notification behavior is the default.

Support for vibration is not yet implemented. It's tracked by #8

s-bauer commented 6 years ago

@huextrat Update to version 0.0.2 of this library. There the default priority is set to HIGH, which means it will be shown as heads up notification with sound/vibration. Custom sound and vibration settings will be added in future version of this plugin.

huextrat commented 6 years ago

@mitchhymel Okay, that's what I thought. Good luck ;) @s-bauer No, version 0.0.2 is a step to reach this state in my opinion since I don't have the heads-up.

s-bauer commented 6 years ago

@huextrat Basically notifications flagged as HIGH or MAX should be shown as a heads up notification. But referring to this stackoverflow answer you apparently also have to set some vibration, even if it's just an empty long array.

@mitchhymel A fix would be to add .setVibrate(new long[0]) to the Notification.Builder if the priority is set to HIGH or MAX

s-bauer commented 6 years ago

@mitchhymel or just set to default sound, vibration and light by using .setDefaults(Notification.DEFAULT_ALL)

rodydavis commented 6 years ago

@mitchhymel I have updated and kept trying to troubleshoot this. On iOS in the simulator and on my iPhone X and iPhone 6s notifications come through perfectly. On the google pixel test device running 8.1.0, I never get a notification. I have checked to make sure the ringer is on, do not disturb is off and I even check the notification center to see if it appears and I never see any notifications. I have tested on the latest flutter, and I am using 'local_notifications: any' in the pub_spec. Since its a google pixel it should have the best support for Android.

mitchhymel commented 6 years ago

Got some good (bad?) news. Tested 0.0.1 and 0.0.2 on my pixel again and neither seem to be working now. This is strange, because I have a flutter app that I built that uses this library (or an earlier version of it) and have been using this for months with no issue, - so it definitely worked at some point. Not sure if this is due to an android/flutter/library change but at least I have a reliable repro to investigate.

huextrat commented 6 years ago

@mitchhymel It can be due to the version 8.1.0 of Android. I have an app currently in development and it works on 8.0.0, I'll test it tomorrow on my Pixel XL under 8.1.0 😉 I think the best thing right now is to implement all the features of a notification and then test it on the different versions of Android

mitchhymel commented 6 years ago

Good news, I've figured out the issue.

In 8.0+ (or SDK 26+) there is a new thing called NotificationChannels. And in 8.0, a notification must have its channel set or it does not get shown. I'll try to make a fix for this over the weekend and push out a new version.

The reason I didn't catch this before was because the library used to be built targeting SDK 25, but I updated it to target SDK 27 for 0.0.2.

I think you should be able to test notifications on your pixel if you use 0.0.1 and make sure your app is targeting SDK 25. I've not yet verified this though.

rodydavis commented 6 years ago

@mitchhymel Awesome thank you! I will update and test when its ready! I was using Android 8.1.0 so that would definitely be why. Awesome plugin by the way!

Also since you have been writing the platform specific code for it, how hard do you think it would be to make a plugin for Firebase Notifications? If you look up all the documentation it all refers to Firebase Messaging, but for me, I just want to add notifications to my app. I would be great if this plugin or a similar one could tell if the app was in the foreground and send a local notification and if it wasn't it could be pushed a firebase notification. I am looking into how to build it. Just curious your thoughts.

mitchhymel commented 6 years ago

I'm not sure I have a good idea of your scenario, but here's me just thinking out loud:

Have you tried the Firebase Cloud Messaging plugin? Specifically take a look at the Receiving Messages documentation, and see if that meets your requirements.

It looks like if you use a "Notification Message", you'll get a basic notification pushed to devices without any extra work. You could alternatively use a "Data Message" to push some data, then in the handling of this push, use this plugin to create your notification. The problem there is that the code to create the notification won't be run if your app is in the background on iOS, or terminated in Android and iOS.

rodydavis commented 6 years ago

Gotcha, I guess it comes down to where you want the notifications getting generated. If you want the app in the background to get notifications then definitely firebase notifications.

Thanks!

mitchhymel commented 6 years ago

I pushed out an update 0.0.3, which supports Android 8.0+. You have to add some extra set up code to create the notification channel. See the README on how to do this, or check the example

rodydavis commented 6 years ago

Thank you! Testing now

rodydavis commented 6 years ago

I updated to local_notifications 0.0.3, Updated flutter to 2.8, and set the android SDK to 23, and followed the examples for android and it is still not showing notifications on the Google Pixel with Android 8.0. and added to manifest: <service android:name="com.mythichelm.localnotifications.services.LocalNotificationsService" android:exported="false" />

iOS still works great. For android it is also not requesting permissions anymore and the user has to go to the app settings to request them.

await LocalNotifications.createAndroidNotificationChannel( channel: channel);

does not fire a notification for android. Any suggestions?

mitchhymel commented 6 years ago

Here's a few things you can try

First, flutter clean from your directory root. Fairly often, I find that the updated dependencies don't actually get pulled in, but a flutter clean should fix this.

If that doesn't work, make sure you've done the following: 1) Create your notification channel (note: this code does not create a notification, it creates a channel)

static const AndroidNotificationChannel channel = const AndroidNotificationChannel(
      id: 'default_notification',
      name: 'CustomNotificationChannel',
      description: 'Grant this app the ability to show notifications',
      importance: AndroidNotificationImportance.DEFAULT,
  );

await LocalNotifications.createAndroidNotificationChannel(
            channel: channel
        );

2) After this code is run, you can validate the channel is created by going into Settings->Apps and Notifications->(Your app)->App notifications. You should see your category listed there similar to below (highlighted with a red box). image

3) Once you've validated the channel was successfully created, then you can create notifications, making sure to provide the same channel info (note: it doesn't have to be the same exact object, but the value of the channel 'id' must be the same)

await LocalNotifications.createNotification(
          id: 0,
          title: 'Basic',
          content: 'some basic notification',
          androidSettings: new AndroidSettings(
            isOngoing: false,
            channel: channel,
            importance: AndroidNotificationImportance.DEFAULT,
          ),
          onNotificationClick: new NotificationAction(
              actionText: "some action",
              callback: removeNotify,
              payload: ""
          )
        );

If after all of that the notification is still not being posted, one other new thing I added in 0.0.3 is better logging. You can turn on logging with await LocalNotifications.setLogging(true); . It will log a message at different steps in the android code to help debug where it is getting stuck or failing.

rodydavis commented 6 years ago

Okay so now it is showing in settings and now when the notification is fired it shows the app icon in the status bar and if I drag down the notifications I can see the one I just made. It works!

On Android is it not supposed to do a banner like iOS if you are in the app? For example in the app I am doing I am displaying a notification when a video has finished processing and I want the user to be notified and possibly select it. This may just be how Android deals with notifications

mitchhymel commented 6 years ago

On iOS, it's my understanding that all notification comes in as a heads up notifications.

On Android, notifications always go to the notification tray, and only show a heads up notification if certain conditions are met.

For Android versions before 8.0, there's not a way to use this library to create a heads up notification yet, because I'm still working on this.

For Android 8.0+, to get a heads up notification behavior on Android similar to iOS, create your notification channel with an importance value of AndroidNotificationImportance.HIGH. Note that users have the ability to go into their system app settings and lower/raise this channel's priority if they are so inclined.

static const AndroidNotificationChannel channel = const AndroidNotificationChannel(
      id: 'some_new_id',
      name: 'CustomNotificationChannel',
      description: 'Grant this app the ability to show notifications',
      importance: AndroidNotificationImportance.HIGH,
  );

I recommend removing your old notification channel and creating a new one with a different id. There seems to be some weirdness with the Android APIs where even if you remove channel with id 'someId' and create a new channel with id 'someId' with a different importance level, the new importance level isn't actually being updated, despite the fact that you can see the old channel was deleted in the app settings. I haven't quite figured out why this happens.

mitchhymel commented 6 years ago

So I actually had the work for Android support for custom vibrate patterns done last week, but didn't have time to test it until today. Was able to test it and it seems to be working so I pushed out an update (0.0.4). I added a section to the README for how to have iOS like heads up notification on all versions of Android.

huextrat commented 6 years ago

Great works!! Are you going to down the minSdkVersion on Android? I think API 23 is quite high atm

rodydavis commented 6 years ago

Yep I am using 23. And FYI when I updated Dart and Flutter this shows in the debug console:

Note: /Users/rodydavis/.pub-cache/hosted/pub.dartlang.org/local_notifications-0.0.4/android/src/main/java/com/mythichelm/localnotifications/factories/NotificationFactory.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: /Users/rodydavis/.pub-cache/hosted/pub.dartlang.org/local_notifications-0.0.4/android/src/main/java/com/mythichelm/localnotifications/factories/NotificationChannelSettingsFactory.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.

And thanks! This really did help a project a lot that I am working on for a company!

huextrat commented 6 years ago

Yeah there is some deprecated functions but anw it works and it could be the best local notification package for flutter if we had compatibility from SDK 16. I think it's not very difficult to do since the notifications were really basic before SDK 23.

mitchhymel commented 6 years ago

I believe I can make the deprecated messages go away and will be able to lower the min sdk if I change the Android APIs to use the support library. This will be the next thing I look into.

mitchhymel commented 6 years ago

I created a separate issue to track the minSdk work (#10 ). Since everything seems to be working for this issue, I'm going to close this.

mitchhymel commented 6 years ago

@AppleEducate The deprecation and unchecked warnings should not show up with v 0.0.6

@huextrat With v 0.0.6, the minSdk is 16. I tested this out on an AVD with SDK 16 and 27, but haven't tested on any other SDK between 16-23.

rodydavis commented 6 years ago

@mitchhymel thanks for those updates!

huextrat commented 6 years ago

@mitchhymel Well done!!