ekasetiawans / flutter_background_service

269 stars 188 forks source link

flutter 3.19.1 new app. Never invoking the listen callback on the 'update' event. #409

Closed teenrage-dev closed 8 months ago

teenrage-dev commented 8 months ago

It's never invoking the listen callback on the 'update' event. I can confirm it's calling the invoke('update') portion and calling on('update').listen, but never receiving the update. It also doesn't seem to be erroring out. Am I missing a step somewhere here?

I add comment in code main.dart //Here i haven't any updates

flutter version 3.19.1 Application created with this flutter version

flutter_background_service: ^5.0.5 flutter_background_service_android: ^6.2.2

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_background_service_test_app/src/backend/index.dart';
import 'package:get_it/get_it.dart';

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

  await initBackend();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  int _counter = 0;

  void _incrementCounter() {
    final backend = GetIt.instance.get<IBackendService>();
    FlutterBackgroundService().on('test1').listen((event) {
    //Here i haven't any  updates
      _counter++;
      setState(() {});
    });
    FlutterBackgroundService().invoke('test1', {'1': '1'});

    backend.onEvent('test1').listen((event) {
    //Here i haven't any  updates
      print('teenrage $event');
      _counter++;
      setState(() {});
    });
    backend.sendEvent('test1', {'1': '1'});
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}

index.dart

import 'package:get_it/get_it.dart';

import 'backend.dart';
import 'backend.interface.dart';
import 'background_process.dart';

export 'backend.dart';
export 'backend.interface.dart';
export 'background_process.dart';

Future<void> initBackend() async {
  final backgroundService = await initBackgroundProcess();
  final backend = BackendService(service: backgroundService);
  GetIt.instance.registerSingleton<IBackendService>(backend);
}

background_process.dart

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_background_service/flutter_background_service.dart';

Future<FlutterBackgroundService> initBackgroundProcess() async {
  final backgroundService = FlutterBackgroundService();

  await backgroundService.configure(
    androidConfiguration: AndroidConfiguration(
      onStart: onStart,
      autoStart: true,
      isForegroundMode: false,
      notificationChannelId: 'test-id',
      initialNotificationTitle: 'test-title',
      initialNotificationContent: 'Syncing ...',
      foregroundServiceNotificationId: 888,
    ),
    iosConfiguration: IosConfiguration(autoStart: true, onForeground: onStart, onBackground: onIosBackground),
  );

  backgroundService.startService();
  return backgroundService;
}

@pragma('vm:entry-point')
Future<bool> onIosBackground(ServiceInstance service) async {
  WidgetsFlutterBinding.ensureInitialized();
  DartPluginRegistrant.ensureInitialized();
  return true;
}

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
  DartPluginRegistrant.ensureInitialized();
}

backend.dart


import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_background_service_test_app/src/backend/backend.interface.dart';

class BackendService implements IBackendService {
  final FlutterBackgroundService service;

  BackendService({required this.service}) {}

  @override
  void sendEvent(String event, Map<String, dynamic> data) {
    service.invoke(event, data);
  }

  @override
  Stream<Map<String, dynamic>?> onEvent(String event) {
    return service.on(event);
  }
}

backend.interface.dart

  void sendEvent(String event, Map<String, dynamic> data);
  Stream<Map<String, dynamic>?> onEvent(String event);
}

package.yaml

description: "A new Flutter project."

publish_to: "none"
version: 1.0.0+1

environment:
  sdk: ">=3.3.0 <4.0.0"

dependencies:
  flutter:
    sdk: flutter
  get_it: ^7.6.7
  rxdart: ^0.27.7
  dio: ^5.4.0
  flutter_background_service: ^5.0.5
  flutter_background_service_android: ^6.2.2

  cupertino_icons: ^1.0.6

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:
  uses-material-design: true

android/gradle/wrapper

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

android/build.gradle

buildscript {
    ext.kotlin_version = '1.8.0'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.4.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

adnroid/settings.gradle

pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }
    settings.ext.flutterSdkPath = flutterSdkPath()

    includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "7.3.0" apply false
    id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}

include ":app"

adnroid/app/buil.gradle

plugins {
    id "com.android.application"
    id "kotlin-android"
    id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

android {
    namespace "com.example.flutter_background_service_test_app"
    compileSdk 34
    ndkVersion flutter.ndkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.flutter_background_service_test_app"
        // You can update the following values to match your application needs.
        // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
        minSdkVersion 21
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

configurations.all {
    resolutionStrategy {
        eachDependency {
            if ((requested.group == "org.jetbrains.kotlin") 
            &&(requested.name.startsWith("kotlin-stdlib"))) {
                useVersion("1.8.0")
            }
        }
    }
}
teenrage-dev commented 8 months ago

Solution.

This library allows the flutter to work in 2 threads. Therefore, the invoke method should be in 2 thread, and in 1 thread you should listen to it. That is, in the on().listen() method