Search code examples
androidflutterandroid-broadcastandroid-appwidgetappwidgetprovider

How can I send a ACTION_APPWIDGET_UPDATE Broadcast from Flutter


In my "java" application, I have this code in my getDataFromServer() function (Which is called by my WorkManager every 2 hours and my MainActivity Onrefresh() ) in order to update my homescreen widget with fresh data:

AppWidgetManager.getInstance(context).getAppWidgetIds(
        new ComponentName(context,MyWidgetProvider.class));
Intent updateIntent = new Intent();
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
updateIntent.putExtra(MyWidgetProvider.WIDGET_ID_KEY, ids);
context.sendBroadcast(updateIntent);

This will make my ,MyAppWidgetProvider to "wake up", to read the fresh data from a file and update.

Now, I have moved my logic to Flutter, and I have no idea how to call this code from my Dart code.

Any suggestion?


Solution

  • You can reference package https://pub.dev/packages/home_widget

    In native part https://github.com/ABausG/home_widget/blob/3de5ff703e9f8f7700036a23e609e0627976f904/android/src/main/kotlin/es/antonborri/home_widget/HomeWidgetPlugin.kt#L61

    "updateWidget" -> {
                    val className = call.argument<String>("android") ?: call.argument<String>("name")
                    try {
                        val javaClass = Class.forName("${context.getPackageName()}.${className}")
                        val intent = Intent(context, javaClass)
                        intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
                        val ids: IntArray = AppWidgetManager.getInstance(context.applicationContext).getAppWidgetIds(ComponentName(context, javaClass))
                        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
                        context.sendBroadcast(intent)
                    } catch (classException: ClassNotFoundException) {
                        result.error("-3", "No Widget found with Name $className. Argument 'name' must be the same as your AppWidgetProvider you wish to update", classException)
                    }
                }
    

    In Dart part for Background Update
    https://pub.dev/packages/home_widget#background-update
    As the methods of HomeWidget are static it is possible to use HomeWidget in the background to update the Widget even when the App is in the background.
    The example App is using the flutter_workmanager plugin to achieve this

    https://github.com/ABausG/home_widget/blob/3de5ff703e9f8f7700036a23e609e0627976f904/example/lib/main.dart#L10

    void callbackDispatcher() {
      Workmanager.executeTask((taskName, inputData) {
        debugPrint('Native called background task: $taskName');
    
        final now = DateTime.now();
        return Future.wait<bool>([
          HomeWidget.saveWidgetData('title', 'Updated from Background'),
          HomeWidget.saveWidgetData('message',
              '${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')} ${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}:${now.second.toString().padLeft(2, '0')}'),
          HomeWidget.updateWidget(
              name: 'HomeWidgetExampleProvider', iOSName: 'HomeWidgetExample'),
        ]).then((value) {
          return !value.contains(false);
        });
      });
    }
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      Workmanager.initialize(callbackDispatcher, isInDebugMode: kDebugMode);
      runApp(MyApp());
    }