Skip to content

🐞Unable to use custom native plugin inside work manager callback. #493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
2 tasks done
BobFactory opened this issue Jul 27, 2023 · 1 comment
Closed
2 tasks done
Labels
bug Something isn't working

Comments

@BobFactory
Copy link

Describe the error

I have a native logic that handles notifications in the Android platform and I wish to use this implementation with Workmanager, but whenever the execution runs I only get this error:
Error: MissingPluginException MissingPluginException(No implementation found for method sendNotification on channel flutter_notification_channel)

I am unaware of how I can register my native plugin with Workmanager. I see that it starts a new Flutter Engine, but that does not register my Native implementation. My native implementation is correct as I have tested that out independently. I am unaware as to how this can work in the new Android v2 bindings.

Code sample

NotficiationPlugin.kt

class NotificationPlugin: FlutterPlugin, MethodChannel.MethodCallHandler {
    private val CHANNEL_NAME = "flutter_notification_channel"

    private var channel: MethodChannel? = null
    private var notificationService: NotificationService? = null

    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        setupChannel(binding.binaryMessenger, binding.applicationContext)
    }

    override fun onDetachedFromEngine(p0: FlutterPlugin.FlutterPluginBinding) {
        teardownChannel();
    }

    private fun setupChannel(messenger: BinaryMessenger, context: Context) {
        channel = MethodChannel(messenger, CHANNEL_NAME)
        channel?.setMethodCallHandler(this)
        notificationService = NotificationService(context)
    }

    private fun teardownChannel() {
        channel?.setMethodCallHandler(null)
        channel = null
        notificationService = null
    }

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        val hashMap = call.arguments as HashMap<*, *>

        when (call.method) {

            "registerChannel" -> {
                val channelId = hashMap["channelId"] as String
                val channelName = hashMap["channelName"] as String
                val channelDescription = hashMap["channelDescription"] as? String ?: ""

                notificationService?.registerChannel(
                    channelId,
                    channelName,
                    channelDescription
                )

                result.success(null)
            }

            "areNotificationsEnabled" -> {
                result.success(notificationService?.isNotificationEnabled)
            }

            "sendNotification" -> {
                val channelId = hashMap["channelId"] as String
                val title = hashMap["title"] as String
                val message = hashMap["message"] as String

                val id = notificationService?.notify(title, message, channelId)
                result.success(id)
            }

            else -> result.notImplemented()

        }
    }

}

MainActivity.kt

class MainActivity : FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        flutterEngine.plugins.add(NotificationPlugin())

    }
}

WorkManager.dart

@pragma('vm:entry-point')
void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) async {
    try {
      var channel = MethodChannel('flutter_notification_channel');

      final args = {
            "channelId": "habit_board_daily_reminder_channel",
            "title": "Helloo",
            "message": "I am a test",
          };

      await channel.invokeMethod("sendNotification", args);
    } catch (e) {
      e.printError();
    }

    return Future.value(true);
  });
}

class WorkManagerService {
  WorkManagerService();

  final _manager = Workmanager();

  Future scheduleReminderChecker() async {
    await _manager.initialize(callbackDispatcher, isInDebugMode: true);

    _manager.registerPeriodicTask(
      "reminder-task",
      "reminder-task",
      existingWorkPolicy: ExistingWorkPolicy.keep,
      frequency: Duration(minutes: 15),
    );
  }

  cancelAll() {
    _manager.cancelAll();
  }
}

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  DartPluginRegistrant.ensureInitialized();
  ///...Also includes some logic to register the notification channel here. 
  await WorkManagerService().scheduleReminderChecker();

  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    statusBarIconBrightness: Brightness.light,
    statusBarBrightness: Brightness.dark,
  ));

runApp(
    Container(
      child: MaterialApp(
        theme: appTheme,
        debugShowCheckedModeBanner: false,
         initialRoute: Routes.HOME,
        defaultTransition: Transition.fade,
      ),
    ),
  );

Version

  • Platform: Android
  • Flutter version: 3.10.5
  • Hive version: [e.g. 0.5.0]
@BobFactory BobFactory added the bug Something isn't working label Jul 27, 2023
@tempo-riz
Copy link

hey @BobFactory did you managed to make it work ? Im also trying #567

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants