├── .idea ├── .name ├── runConfigurations │ ├── melos_flutter_run_example.xml │ ├── melos_flutter_test_flutter_background_service.xml │ ├── melos_flutter_test_flutter_background_service_ios.xml │ ├── melos_flutter_test_flutter_background_service_android.xml │ ├── melos_flutter_test_flutter_background_service_platform_interface.xml │ ├── melos_clean.xml │ ├── melos_bootstrap.xml │ └── melos_run_postclean.xml └── modules.xml ├── .gitignore ├── packages ├── flutter_background_service_ios │ ├── ios │ │ ├── Assets │ │ │ └── .gitkeep │ │ ├── Classes │ │ │ ├── FlutterBackgroundServicePlugin.h │ │ │ └── FlutterBackgroundServicePlugin.m │ │ ├── .gitignore │ │ └── flutter_background_service_ios.podspec │ ├── test │ │ └── flutter_background_service_test.dart │ ├── .vscode │ │ └── settings.json │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── flutter_background_service.iml │ ├── LICENSE │ ├── melos_flutter_background_service_ios.iml │ ├── pubspec.yaml │ └── lib │ │ └── flutter_background_service_ios.dart ├── flutter_background_service │ ├── test │ │ └── flutter_background_service_test.dart │ ├── .vscode │ │ └── settings.json │ ├── example │ │ ├── ios │ │ │ ├── Runner │ │ │ │ ├── Runner-Bridging-Header.h │ │ │ │ ├── Assets.xcassets │ │ │ │ │ ├── LaunchImage.imageset │ │ │ │ │ │ ├── LaunchImage.png │ │ │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Base.lproj │ │ │ │ │ ├── Main.storyboard │ │ │ │ │ └── LaunchScreen.storyboard │ │ │ │ └── Info.plist │ │ │ ├── Flutter │ │ │ │ ├── Debug.xcconfig │ │ │ │ ├── Release.xcconfig │ │ │ │ └── AppFrameworkInfo.plist │ │ │ ├── Runner.xcodeproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ └── Runner.xcscheme │ │ │ ├── Runner.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ ├── .gitignore │ │ │ ├── Podfile │ │ │ └── Podfile.lock │ │ ├── android │ │ │ ├── gradle.properties │ │ │ ├── app │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ ├── kotlin │ │ │ │ │ │ │ └── id │ │ │ │ │ │ │ │ └── flutter │ │ │ │ │ │ │ │ └── example │ │ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ │ ├── res │ │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ │ │ ├── values │ │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ │ │ └── values-night │ │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ │ ├── debug │ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ │ └── profile │ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── build.gradle │ │ │ ├── gradle │ │ │ │ └── wrapper │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── .gitignore │ │ │ ├── settings.gradle │ │ │ └── build.gradle │ │ ├── web │ │ │ ├── favicon.png │ │ │ ├── icons │ │ │ │ ├── Icon-192.png │ │ │ │ ├── Icon-512.png │ │ │ │ ├── Icon-maskable-192.png │ │ │ │ └── Icon-maskable-512.png │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── windows │ │ │ ├── runner │ │ │ │ ├── resources │ │ │ │ │ └── app_icon.ico │ │ │ │ ├── resource.h │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── utils.h │ │ │ │ ├── runner.exe.manifest │ │ │ │ ├── flutter_window.h │ │ │ │ ├── main.cpp │ │ │ │ ├── utils.cpp │ │ │ │ ├── flutter_window.cpp │ │ │ │ ├── Runner.rc │ │ │ │ ├── win32_window.h │ │ │ │ └── win32_window.cpp │ │ │ ├── flutter │ │ │ │ ├── generated_plugin_registrant.cc │ │ │ │ ├── generated_plugin_registrant.h │ │ │ │ ├── generated_plugins.cmake │ │ │ │ └── CMakeLists.txt │ │ │ ├── .gitignore │ │ │ └── CMakeLists.txt │ │ ├── .metadata │ │ ├── .vscode │ │ │ └── launch.json │ │ ├── test │ │ │ └── widget_test.dart │ │ ├── README.md │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── analysis_options.yaml │ │ ├── pubspec.yaml │ │ └── lib │ │ │ └── main.dart │ ├── .gitignore │ ├── .metadata │ ├── flutter_background_service.iml │ ├── LICENSE │ ├── pubspec.yaml │ ├── melos_flutter_background_service.iml │ └── lib │ │ └── flutter_background_service.dart ├── flutter_background_service_android │ ├── test │ │ └── flutter_background_service_test.dart │ ├── .vscode │ │ └── settings.json │ ├── android │ │ ├── settings.gradle │ │ ├── .gitignore │ │ ├── gradle.properties │ │ ├── proguard-rules.pro │ │ ├── src │ │ │ └── main │ │ │ │ ├── res │ │ │ │ ├── drawable-hdpi │ │ │ │ │ └── ic_bg_service_small.png │ │ │ │ ├── drawable-mdpi │ │ │ │ │ └── ic_bg_service_small.png │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── ic_bg_service_small.png │ │ │ │ └── drawable-xxhdpi │ │ │ │ │ └── ic_bg_service_small.png │ │ │ │ ├── java │ │ │ │ └── id │ │ │ │ │ └── flutter │ │ │ │ │ └── flutter_background_service │ │ │ │ │ ├── Pipe.java │ │ │ │ │ ├── BootReceiver.java │ │ │ │ │ ├── ForegroundTypeMapper.java │ │ │ │ │ ├── Config.java │ │ │ │ │ ├── WatchdogReceiver.java │ │ │ │ │ └── FlutterBackgroundServicePlugin.java │ │ │ │ └── AndroidManifest.xml │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ └── build.gradle │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── flutter_background_service.iml │ ├── LICENSE │ ├── melos_flutter_background_service_android.iml │ ├── pubspec.yaml │ └── lib │ │ └── flutter_background_service_android.dart ├── .DS_Store └── flutter_background_service_platform_interface │ ├── test │ └── flutter_background_service_platform_interface_test.dart │ ├── analysis_options.yaml │ ├── .metadata │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── lib │ ├── flutter_background_service_platform_interface.dart │ └── src │ │ └── configs.dart │ ├── pubspec.yaml │ └── CHANGELOG.md ├── .vscode ├── settings.json └── launch.json ├── .DS_Store ├── pubspec.yaml ├── examples └── simple-example-with-socketio │ ├── main.dart │ └── background_service.dart ├── melos.yaml ├── melos_flutter_background_service.iml ├── .github └── workflows │ └── pub.yml └── pubspec.lock /.idea/.name: -------------------------------------------------------------------------------- 1 | flutter_background_service -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/pubspec_overrides.yaml 2 | .dart_tool/** -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dart.runPubGetOnPubspecChanges": false 3 | } -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/.DS_Store -------------------------------------------------------------------------------- /packages/flutter_background_service/test/flutter_background_service_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/test/flutter_background_service_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/test/flutter_background_service_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /packages/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/.DS_Store -------------------------------------------------------------------------------- /packages/flutter_background_service/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dart.runPubGetOnPubspecChanges": false 3 | } -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dart.runPubGetOnPubspecChanges": false 3 | } -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dart.runPubGetOnPubspecChanges": false 3 | } -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_background_service' 2 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/test/flutter_background_service_platform_interface_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /packages/flutter_background_service/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | pubspec.lock 9 | .idea/ 10 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | pubspec.lock 9 | .idea/ 10 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | pubspec.lock 9 | .idea/ 10 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_background_service 2 | 3 | environment: 4 | sdk: ">=2.17.5 <4.0.0" 5 | flutter: ">=3.0.0" 6 | 7 | dependencies: 8 | melos: ^6.1.0 9 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/web/favicon.png -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -keep class id.flutter.flutter_background_service.** { *; } 2 | -keepclassmembers class id.flutter.flutter_background_service.** {*;} -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /examples/simple-example-with-socketio/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | Future main() async { 4 | WidgetsFlutterBinding.ensureInitialized(); 5 | await initializeService(); 6 | runApp(MyApp()); 7 | } 8 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/kotlin/id/flutter/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package id.flutter.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/ios/Classes/FlutterBackgroundServicePlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterBackgroundServicePlugin : NSObject 4 | + (void)registerEngine:(FlutterEngine*)engine; 5 | @end 6 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/res/drawable-hdpi/ic_bg_service_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service_android/android/src/main/res/drawable-hdpi/ic_bg_service_small.png -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/res/drawable-mdpi/ic_bg_service_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service_android/android/src/main/res/drawable-mdpi/ic_bg_service_small.png -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/res/drawable-xhdpi/ic_bg_service_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service_android/android/src/main/res/drawable-xhdpi/ic_bg_service_small.png -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/res/drawable-xxhdpi/ic_bg_service_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service_android/android/src/main/res/drawable-xxhdpi/ic_bg_service_small.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/flutter_background_service/master/packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void RegisterPlugins(flutter::PluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 7 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/flutter_background_service/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 216dee60c0cc9449f0b29bcf922974d612263e24 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 216dee60c0cc9449f0b29bcf922974d612263e24 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_flutter_run_example.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 216dee60c0cc9449f0b29bcf922974d612263e24 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 216dee60c0cc9449f0b29bcf922974d612263e24 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7e9793dee1b85a243edd0e06cb1658e98b077561 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_flutter_test_flutter_background_service.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_flutter_test_flutter_background_service_ios.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_flutter_test_flutter_background_service_android.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "example", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /packages/flutter_background_service/example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | 9 | 10 | void main() {} 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_flutter_test_flutter_background_service_platform_interface.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/README.md: -------------------------------------------------------------------------------- 1 | # flutter\_background\_service\_ios 2 | 3 | The iOS implementation of [`flutter_background_service`][1]. 4 | 5 | ## Usage 6 | 7 | This package is [endorsed][2], which means you can simply use `flutter_background_service` 8 | normally. This package will be automatically included in your app when you do. 9 | 10 | [1]: https://pub.dev/packages/flutter_background_service 11 | [2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin -------------------------------------------------------------------------------- /packages/flutter_background_service_android/README.md: -------------------------------------------------------------------------------- 1 | # flutter\_background\_service\_android 2 | 3 | The Android implementation of [`flutter_background_service`][1]. 4 | 5 | ## Usage 6 | 7 | This package is [endorsed][2], which means you can simply use `flutter_background_service` 8 | normally. This package will be automatically included in your app when you do. 9 | 10 | [1]: https://pub.dev/packages/flutter_background_service 11 | [2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin -------------------------------------------------------------------------------- /melos.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_background_service 2 | repository: https://github.com/ekasetiawans/flutter_background_service 3 | 4 | packages: 5 | - packages/** 6 | 7 | command: 8 | version: 9 | # Generate commit links in package changelogs. 10 | linkToCommits: true 11 | # Only allow versioning to happen on main branch. 12 | branch: master 13 | # Additionally build a changelog at the root of the workspace. 14 | workspaceChangelog: true 15 | 16 | scripts: 17 | postclean: > 18 | melos exec -c 6 -- "flutter clean" 19 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /melos_flutter_background_service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_clean.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_bootstrap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/runConfigurations/melos_run_postclean.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | import flutter_background_service_ios 4 | 5 | @UIApplicationMain 6 | @objc class AppDelegate: FlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | SwiftFlutterBackgroundServicePlugin.taskIdentifier = "dev.flutter.background.refresh" 12 | GeneratedPluginRegistrant.register(with: self) 13 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | add_executable(${BINARY_NAME} WIN32 5 | "flutter_window.cpp" 6 | "main.cpp" 7 | "utils.cpp" 8 | "win32_window.cpp" 9 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 10 | "Runner.rc" 11 | "runner.exe.manifest" 12 | ) 13 | apply_standard_settings(${BINARY_NAME}) 14 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 15 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 16 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 17 | add_dependencies(${BINARY_NAME} flutter_assemble) 18 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 25 | /pubspec.lock 26 | **/doc/api/ 27 | .dart_tool/ 28 | .packages 29 | build/ 30 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_background_service_example 2 | 3 | Demonstrates how to use the flutter_background_service plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.8.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.4.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'id.flutter.flutter_background_service' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:7.4.2' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 34 26 | namespace = "id.flutter.flutter_background_service" 27 | defaultConfig { 28 | minSdkVersion 16 29 | consumerProguardFiles 'proguard-rules.pro' 30 | } 31 | 32 | lintOptions { 33 | disable 'InvalidPackage' 34 | } 35 | } 36 | 37 | dependencies { 38 | implementation "androidx.core:core:1.12.0" 39 | } 40 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter: Attach to Device", 9 | "type": "dart", 10 | "request": "attach" 11 | }, 12 | { 13 | "name": "example", 14 | "cwd": "packages/flutter_background_service/example", 15 | "request": "launch", 16 | "type": "dart" 17 | }, 18 | { 19 | "name": "example (release)", 20 | "cwd": "packages/flutter_background_service/example", 21 | "request": "launch", 22 | "type": "dart", 23 | "flutterMode": "release" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.0.0 2 | 3 | > Note: This release has breaking changes. 4 | 5 | - **REFACTOR**: fix sampe project dependency version. ([a83b9f62](https://github.com/ekasetiawans/flutter_background_service/commit/a83b9f62dd0d16f8bd23657ef1f36cb7d51fb0fa)) 6 | - **FIX**: errors. ([13a6f841](https://github.com/ekasetiawans/flutter_background_service/commit/13a6f841f5d677ceb0010e8ba1bf9d7af53adbcf)) 7 | - **FIX**: podspec. ([b46f9a3f](https://github.com/ekasetiawans/flutter_background_service/commit/b46f9a3f425f66e6bda34650e713da299f922a73)) 8 | - **FEAT**: managed with melos. ([2313273a](https://github.com/ekasetiawans/flutter_background_service/commit/2313273a3e728e37e2fb973ccc146841c8af48da)) 9 | - **DOCS**: change method name. ([9f05e7f6](https://github.com/ekasetiawans/flutter_background_service/commit/9f05e7f6a260d8f63788cb21e8e7c2cdc91769eb)) 10 | - **BREAKING** **FEAT**: implement new concept. ([c8ce9c0b](https://github.com/ekasetiawans/flutter_background_service/commit/c8ce9c0bab82137dea031af124b84510286661f7)) 11 | 12 | -------------------------------------------------------------------------------- /packages/flutter_background_service/flutter_background_service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/flutter_background_service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/flutter_background_service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/flutter_background_service/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Eka Setiawan Saputra 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Eka Setiawan Saputra 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/flutter_background_service_android/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Eka Setiawan Saputra 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/ios/flutter_background_service_ios.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_background_service.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_background_service_ios' 7 | s.version = '0.0.3' 8 | s.summary = 'A new flutter plugin project.' 9 | s.description = <<-DESC 10 | A new flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Eka Setiawan Saputra 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/README.md: -------------------------------------------------------------------------------- 1 | # flutter_background_service_platform_interface 2 | 3 | A common platform interface for the [`flutter_background_service`][1] plugin. 4 | 5 | This interface allows platform-specific implementations of the `flutter_background_service` 6 | plugin, as well as the plugin itself, to ensure they are supporting the 7 | same interface. 8 | 9 | # Usage 10 | 11 | To implement a new platform-specific implementation of `flutter_background_service`, extend 12 | [`FlutterBackgroundServicePlatform`][2] with an implementation that performs the 13 | platform-specific behavior, and when you register your plugin, set the default 14 | `FlutterBackgroundServicePlatform` by calling 15 | `FlutterBackgroundServicePlatform.instance = MyPlatformPathProvider()`. 16 | 17 | # Note on breaking changes 18 | 19 | Strongly prefer non-breaking changes (such as adding a method to the interface) 20 | over breaking changes for this package. 21 | 22 | See https://flutter.dev/go/platform-interface-breaking-changes for a discussion 23 | on why a less-clean interface is preferable to a breaking change. 24 | 25 | [1]: ../ 26 | [2]: lib/flutter_background_service_platform_interface.dart -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/java/id/flutter/flutter_background_service/Pipe.java: -------------------------------------------------------------------------------- 1 | package id.flutter.flutter_background_service; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Pipe { 9 | public interface PipeListener { 10 | public void onReceived(JSONObject object); 11 | } 12 | 13 | private final List listeners = new ArrayList<>(); 14 | public boolean hasListener() { 15 | return !listeners.isEmpty(); 16 | } 17 | 18 | public void addListener(PipeListener listener){ 19 | synchronized (this){ 20 | this.listeners.add(listener); 21 | } 22 | } 23 | 24 | public void removeListener(PipeListener listener){ 25 | synchronized (this){ 26 | this.listeners.remove(listener); 27 | } 28 | } 29 | 30 | public void invoke(JSONObject object){ 31 | synchronized (this) { 32 | if (!listeners.isEmpty()) { 33 | for (PipeListener listener : 34 | this.listeners) { 35 | listener.onReceived(object); 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/flutter_background_service/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_background_service 2 | description: A flutter plugin for executing dart code continously even application closed. 3 | version: 5.0.10 4 | repository: https://github.com/ekasetiawans/flutter_background_service 5 | 6 | funding: 7 | - https://www.buymeacoffee.com/ekasetiawans 8 | 9 | environment: 10 | sdk: ">=2.17.5 <4.0.0" 11 | flutter: ">=3.0.0" 12 | 13 | dependencies: 14 | flutter: 15 | sdk: flutter 16 | 17 | flutter_background_service_platform_interface: ^5.1.2 18 | flutter_background_service_android: ^6.2.7 19 | flutter_background_service_ios: ^5.0.3 20 | dev_dependencies: 21 | flutter_test: 22 | sdk: flutter 23 | 24 | # For information on the generic Dart part of this file, see the 25 | # following page: https://dart.dev/tools/pub/pubspec 26 | 27 | # The following section is specific to Flutter. 28 | flutter: 29 | # This section identifies this Flutter project as a plugin project. 30 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 31 | # be modified. They are used by the tooling to maintain consistency when 32 | # adding or updating assets for this project. 33 | plugin: 34 | platforms: 35 | android: 36 | default_package: flutter_background_service_android 37 | ios: 38 | default_package: flutter_background_service_ios 39 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/java/id/flutter/flutter_background_service/BootReceiver.java: -------------------------------------------------------------------------------- 1 | package id.flutter.flutter_background_service; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.BroadcastReceiver; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | 8 | import androidx.core.content.ContextCompat; 9 | 10 | 11 | public class BootReceiver extends BroadcastReceiver { 12 | @SuppressLint("WakelockTimeout") 13 | @Override 14 | public void onReceive(Context context, Intent intent) { 15 | if (intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED) || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) || intent.getAction().equals("android.intent.action.QUICKBOOT_POWERON")) { 16 | final Config config = new Config(context); 17 | boolean autoStart = config.isAutoStartOnBoot(); 18 | if (autoStart) { 19 | if (BackgroundService.lockStatic == null) { 20 | BackgroundService.getLock(context).acquire(); 21 | } 22 | 23 | if (config.isForeground()) { 24 | ContextCompat.startForegroundService(context, new Intent(context, BackgroundService.class)); 25 | } else { 26 | context.startService(new Intent(context, BackgroundService.class)); 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.CreateAndShow(L"example", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/ios/Classes/FlutterBackgroundServicePlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterBackgroundServicePlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "flutter_background_service_ios-Swift.h" 9 | #endif 10 | 11 | @interface GeneratedPluginRegistrant : NSObject 12 | + (void)registerWithRegistry:(NSObject*)registry; 13 | @end 14 | 15 | 16 | @implementation FlutterBackgroundServicePlugin 17 | + (void)registerWithRegistrar:(NSObject*)registrar { 18 | [SwiftFlutterBackgroundServicePlugin registerWithRegistrar:registrar]; 19 | } 20 | 21 | + (void)setPluginRegistrantCallback:(FlutterPluginRegistrantCallback)callback { 22 | [SwiftFlutterBackgroundServicePlugin setPluginRegistrantCallback:callback]; 23 | } 24 | 25 | + (nullable Class)lookupGeneratedPluginRegistrant { 26 | NSString* classNameToCompare = @"GeneratedPluginRegistrant"; 27 | return NSClassFromString(classNameToCompare); 28 | } 29 | 30 | + (void)registerEngine:(FlutterEngine*)engine { 31 | [[FlutterBackgroundServicePlugin lookupGeneratedPluginRegistrant] registerWithRegistry:engine]; 32 | } 33 | @end 34 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/pub.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Pub 7 | 8 | on: 9 | push: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | fetch-depth: 0 20 | - name: Prepare credentials 21 | run: | 22 | mkdir ~/.config/dart 23 | echo ${{ secrets.PUB_CREDENTIAL }} | base64 --decode > ~/.config/dart/pub-credentials.json 24 | - name: Setup git 25 | run: | 26 | git config --local user.email "mr.poetra22@gmail.com" 27 | git config --local user.name "Eka Setiawan Saputra" 28 | - name: Install Flutter 29 | id: install 30 | continue-on-error: true 31 | uses: subosito/flutter-action@v1 32 | with: 33 | channel: "stable" 34 | - name: 'Get Dependencies' 35 | run: flutter pub get 36 | - name: 'Install melos' 37 | run: dart pub global activate melos 38 | - name: 'Update versions' 39 | run: melos version --yes 40 | 41 | - name: Push changes 42 | uses: ad-m/github-push-action@master 43 | with: 44 | github_token: ${{ secrets.GIT_PAT }} 45 | branch: master 46 | tags: true 47 | 48 | - name: 'Publish to pub.dev' 49 | run: melos publish --no-dry-run -y 50 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - device_info_plus (0.0.1): 3 | - Flutter 4 | - Flutter (1.0.0) 5 | - flutter_background_service_ios (0.0.3): 6 | - Flutter 7 | - flutter_local_notifications (0.0.1): 8 | - Flutter 9 | - shared_preferences_ios (0.0.1): 10 | - Flutter 11 | 12 | DEPENDENCIES: 13 | - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) 14 | - Flutter (from `Flutter`) 15 | - flutter_background_service_ios (from `.symlinks/plugins/flutter_background_service_ios/ios`) 16 | - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) 17 | - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) 18 | 19 | EXTERNAL SOURCES: 20 | device_info_plus: 21 | :path: ".symlinks/plugins/device_info_plus/ios" 22 | Flutter: 23 | :path: Flutter 24 | flutter_background_service_ios: 25 | :path: ".symlinks/plugins/flutter_background_service_ios/ios" 26 | flutter_local_notifications: 27 | :path: ".symlinks/plugins/flutter_local_notifications/ios" 28 | shared_preferences_ios: 29 | :path: ".symlinks/plugins/shared_preferences_ios/ios" 30 | 31 | SPEC CHECKSUMS: 32 | device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed 33 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 34 | flutter_background_service_ios: e30e0d3ee69e4cee66272d0c78eacd48c2e94aac 35 | flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 36 | shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad 37 | 38 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 39 | 40 | COCOAPODS: 1.11.3 41 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/lib/flutter_background_service_platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter_background_service_platform_interface/src/configs.dart'; 4 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 5 | 6 | export 'src/configs.dart'; 7 | 8 | abstract class Observable { 9 | void invoke(String method, [Map? args]); 10 | Stream?> on(String method); 11 | } 12 | 13 | abstract class FlutterBackgroundServicePlatform extends PlatformInterface 14 | implements Observable { 15 | FlutterBackgroundServicePlatform() : super(token: _token); 16 | static final Object _token = Object(); 17 | 18 | static FlutterBackgroundServicePlatform? _instance; 19 | 20 | static FlutterBackgroundServicePlatform get instance { 21 | if (_instance == null) { 22 | throw 'FlutterBackgroundService is currently supported for Android and iOS Platform only.'; 23 | } 24 | 25 | return _instance!; 26 | } 27 | 28 | /// Platform-specific plugins should set this with their own platform-specific 29 | /// class that extends [FlutterBackgroundServicePlatform] when they register themselves. 30 | static set instance(FlutterBackgroundServicePlatform instance) { 31 | PlatformInterface.verify(instance, _token); 32 | _instance = instance; 33 | } 34 | 35 | Future configure({ 36 | required IosConfiguration iosConfiguration, 37 | required AndroidConfiguration androidConfiguration, 38 | }); 39 | 40 | Future start(); 41 | 42 | Future isServiceRunning(); 43 | } 44 | 45 | abstract class ServiceInstance implements Observable { 46 | /// Stop the service 47 | Future stopSelf(); 48 | } 49 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/flutter_background_service/melos_flutter_background_service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/melos_flutter_background_service_ios.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/melos_flutter_background_service_android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/flutter_background_service/lib/flutter_background_service.dart: -------------------------------------------------------------------------------- 1 | library flutter_background_service; 2 | 3 | import 'dart:async'; 4 | 5 | import 'package:flutter_background_service_platform_interface/flutter_background_service_platform_interface.dart'; 6 | 7 | export 'package:flutter_background_service_platform_interface/flutter_background_service_platform_interface.dart' 8 | show IosConfiguration, AndroidConfiguration, ServiceInstance, AndroidForegroundType; 9 | 10 | export 'package:flutter_background_service_android/flutter_background_service_android.dart'; 11 | export 'package:flutter_background_service_ios/flutter_background_service_ios.dart'; 12 | 13 | class FlutterBackgroundService implements Observable { 14 | FlutterBackgroundServicePlatform get _platform => 15 | FlutterBackgroundServicePlatform.instance; 16 | 17 | /// configure the background service handler 18 | /// it's highly recommended to call this method in main() method 19 | Future configure({ 20 | required IosConfiguration iosConfiguration, 21 | required AndroidConfiguration androidConfiguration, 22 | }) => 23 | _platform.configure( 24 | iosConfiguration: iosConfiguration, 25 | androidConfiguration: androidConfiguration, 26 | ); 27 | 28 | static FlutterBackgroundService _instance = 29 | FlutterBackgroundService._internal(); 30 | 31 | FlutterBackgroundService._internal(); 32 | 33 | factory FlutterBackgroundService() => _instance; 34 | 35 | /// Starts the background service. 36 | Future startService() => _platform.start(); 37 | 38 | /// Whether the service is running 39 | Future isRunning() => _platform.isServiceRunning(); 40 | 41 | @override 42 | void invoke(String method, [Map? arg]) => 43 | _platform.invoke(method, arg); 44 | 45 | @override 46 | Stream?> on(String method) => _platform.on(method); 47 | } 48 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | if (target_length == 0) { 52 | return std::string(); 53 | } 54 | std::string utf8_string; 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_background_service_platform_interface 2 | description: A platform interface for flutter background service. 3 | version: 5.1.2 4 | repository: https://github.com/ekasetiawans/flutter_background_service 5 | 6 | environment: 7 | sdk: ">=2.17.5 <4.0.0" 8 | flutter: ">=3.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | platform: ^3.1.0 15 | plugin_platform_interface: ^2.1.2 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | flutter_lints: ^4.0.0 21 | 22 | # For information on the generic Dart part of this file, see the 23 | # following page: https://dart.dev/tools/pub/pubspec 24 | 25 | # The following section is specific to Flutter. 26 | # flutter: 27 | 28 | # To add assets to your package, add an assets section, like this: 29 | # assets: 30 | # - images/a_dot_burr.jpeg 31 | # - images/a_dot_ham.jpeg 32 | # 33 | # For details regarding assets in packages, see 34 | # https://flutter.dev/assets-and-images/#from-packages 35 | # 36 | # An image asset can refer to one or more resolution-specific "variants", see 37 | # https://flutter.dev/assets-and-images/#resolution-aware. 38 | 39 | # To add custom fonts to your package, add a fonts section here, 40 | # in this "flutter" section. Each entry in this list should have a 41 | # "family" key with the font family name, and a "fonts" key with a 42 | # list giving the asset and other descriptors for the font. For 43 | # example: 44 | # fonts: 45 | # - family: Schyler 46 | # fonts: 47 | # - asset: fonts/Schyler-Regular.ttf 48 | # - asset: fonts/Schyler-Italic.ttf 49 | # style: italic 50 | # - family: Trajan Pro 51 | # fonts: 52 | # - asset: fonts/TrajanPro.ttf 53 | # - asset: fonts/TrajanPro_Bold.ttf 54 | # weight: 700 55 | # 56 | # For details regarding fonts in packages, see 57 | # https://flutter.dev/custom-fonts/#from-packages 58 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | return true; 30 | } 31 | 32 | void FlutterWindow::OnDestroy() { 33 | if (flutter_controller_) { 34 | flutter_controller_ = nullptr; 35 | } 36 | 37 | Win32Window::OnDestroy(); 38 | } 39 | 40 | LRESULT 41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 42 | WPARAM const wparam, 43 | LPARAM const lparam) noexcept { 44 | // Give Flutter, including plugins, an opportunity to handle window messages. 45 | if (flutter_controller_) { 46 | std::optional result = 47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 48 | lparam); 49 | if (result) { 50 | return *result; 51 | } 52 | } 53 | 54 | switch (message) { 55 | case WM_FONTCHANGE: 56 | flutter_controller_->engine()->ReloadSystemFonts(); 57 | break; 58 | } 59 | 60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 61 | } 62 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BGTaskSchedulerPermittedIdentifiers 6 | 7 | dev.flutter.background.refresh 8 | 9 | CFBundleDevelopmentRegion 10 | $(DEVELOPMENT_LANGUAGE) 11 | CFBundleDisplayName 12 | Example 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | example 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | $(FLUTTER_BUILD_NAME) 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | $(FLUTTER_BUILD_NUMBER) 29 | LSRequiresIPhoneOS 30 | 31 | UIBackgroundModes 32 | 33 | fetch 34 | 35 | UILaunchStoryboardName 36 | LaunchScreen 37 | UIMainStoryboardFile 38 | Main 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | CADisableMinimumFrameDurationOnPhone 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/java/id/flutter/flutter_background_service/ForegroundTypeMapper.java: -------------------------------------------------------------------------------- 1 | package id.flutter.flutter_background_service; 2 | 3 | import android.app.Service; 4 | import android.content.pm.ServiceInfo; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class ForegroundTypeMapper { 9 | 10 | private static final Map foregroundTypeMap = new HashMap<>(); 11 | 12 | static { 13 | foregroundTypeMap.put("camera", ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA); 14 | foregroundTypeMap.put("connectedDevice", ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE); 15 | foregroundTypeMap.put("dataSync", ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC); 16 | foregroundTypeMap.put("health", ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH); 17 | foregroundTypeMap.put("location", ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION); 18 | foregroundTypeMap.put("mediaPlayback", ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK); 19 | foregroundTypeMap.put("mediaProjection", ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION); 20 | foregroundTypeMap.put("microphone", ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE); 21 | foregroundTypeMap.put("phoneCall", ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL); 22 | foregroundTypeMap.put("remoteMessaging", ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING); 23 | foregroundTypeMap.put("shortService", ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE); 24 | foregroundTypeMap.put("specialUse", ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE); 25 | foregroundTypeMap.put("systemExempted", ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED); 26 | } 27 | 28 | public static Integer getForegroundServiceType(String[] foregroundTypes) { 29 | Integer foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; 30 | if (foregroundTypes != null && foregroundTypes.length > 0) { 31 | foregroundServiceType = 0; 32 | for (String foregroundType : foregroundTypes) { 33 | foregroundServiceType |= foregroundTypeMap.get(foregroundType); 34 | } 35 | } 36 | return foregroundServiceType; 37 | } 38 | } -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 34 30 | 31 | // compileOptions { 32 | // sourceCompatibility JavaVersion.VERSION_1_8 33 | // targetCompatibility JavaVersion.VERSION_1_8 34 | // } 35 | // 36 | // kotlinOptions { 37 | // jvmTarget = '1.8' 38 | // } 39 | 40 | sourceSets { 41 | main.java.srcDirs += 'src/main/kotlin' 42 | } 43 | 44 | defaultConfig { 45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 46 | applicationId "id.flutter.example" 47 | minSdkVersion flutter.minSdkVersion 48 | targetSdkVersion flutter.targetSdkVersion 49 | versionCode flutterVersionCode.toInteger() 50 | versionName flutterVersionName 51 | } 52 | 53 | buildTypes { 54 | release { 55 | // TODO: Add your own signing config for the release build. 56 | // Signing with the debug keys for now, so `flutter run --release` works. 57 | signingConfig signingConfigs.debug 58 | } 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 68 | } 69 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 16 | 17 | 25 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_background_service_ios 2 | description: A flutter plugin for executing dart code continously even application closed. 3 | version: 5.0.3 4 | repository: https://github.com/ekasetiawans/flutter_background_service 5 | 6 | environment: 7 | sdk: ">=2.17.5 <4.0.0" 8 | flutter: ">=3.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | flutter_background_service_platform_interface: ^5.1.2 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://dart.dev/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter. 23 | flutter: 24 | # This section identifies this Flutter project as a plugin project. 25 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 26 | # be modified. They are used by the tooling to maintain consistency when 27 | # adding or updating assets for this project. 28 | plugin: 29 | implements: flutter_background_service 30 | platforms: 31 | ios: 32 | pluginClass: FlutterBackgroundServicePlugin 33 | dartPluginClass: FlutterBackgroundServiceIOS 34 | # To add assets to your plugin package, add an assets section, like this: 35 | # assets: 36 | # - images/a_dot_burr.jpeg 37 | # - images/a_dot_ham.jpeg 38 | # 39 | # For details regarding assets in packages, see 40 | # https://flutter.dev/assets-and-images/#from-packages 41 | # 42 | # An image asset can refer to one or more resolution-specific "variants", see 43 | # https://flutter.dev/assets-and-images/#resolution-aware. 44 | # To add custom fonts to your plugin package, add a fonts section here, 45 | # in this "flutter" section. Each entry in this list should have a 46 | # "family" key with the font family name, and a "fonts" key with a 47 | # list giving the asset and other descriptors for the font. For 48 | # example: 49 | # fonts: 50 | # - family: Schyler 51 | # fonts: 52 | # - asset: fonts/Schyler-Regular.ttf 53 | # - asset: fonts/Schyler-Italic.ttf 54 | # style: italic 55 | # - family: Trajan Pro 56 | # fonts: 57 | # - asset: fonts/TrajanPro.ttf 58 | # - asset: fonts/TrajanPro_Bold.ttf 59 | # weight: 700 60 | # 61 | # For details regarding fonts in packages, see 62 | # https://flutter.dev/custom-fonts/#from-packages 63 | -------------------------------------------------------------------------------- /examples/simple-example-with-socketio/background_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:ui'; 3 | import 'package:socket_io_client/socket_io_client.dart' as io; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_background_service/flutter_background_service.dart'; 6 | 7 | void startBackgroundService() { 8 | final service = FlutterBackgroundService(); 9 | service.startService(); 10 | } 11 | 12 | void stopBackgroundService() { 13 | final service = FlutterBackgroundService(); 14 | service.invoke("stop"); 15 | } 16 | 17 | Future initializeService() async { 18 | final service = FlutterBackgroundService(); 19 | 20 | await service.configure( 21 | iosConfiguration: IosConfiguration( 22 | autoStart: true, 23 | onForeground: onStart, 24 | onBackground: onIosBackground, 25 | ), 26 | androidConfiguration: AndroidConfiguration( 27 | autoStart: true, 28 | onStart: onStart, 29 | isForegroundMode: false, 30 | autoStartOnBoot: true, 31 | ), 32 | ); 33 | } 34 | 35 | @pragma('vm:entry-point') 36 | Future onIosBackground(ServiceInstance service) async { 37 | WidgetsFlutterBinding.ensureInitialized(); 38 | DartPluginRegistrant.ensureInitialized(); 39 | 40 | return true; 41 | } 42 | 43 | @pragma('vm:entry-point') 44 | void onStart(ServiceInstance service) async { 45 | 46 | io.Socket socket = io.io('ws://10.0.2.2:5000', //specify your own socket ip and port 47 | io.OptionBuilder() 48 | .setTransports(['websocket']) // for Flutter or Dart VM 49 | .enableAutoConnect() // disable auto-connection 50 | .setExtraHeaders({'foo': 'bar'}) // optional 51 | .build() 52 | ); 53 | socket.connect(); 54 | socket.onConnect((_) { 55 | print('Connected. Socket ID: ${socket.id}'); 56 | // Implement your socket logic here 57 | // For example, you can listen for events or send data 58 | }); 59 | 60 | socket.onDisconnect((_) { 61 | print('Disconnected'); 62 | }); 63 | socket.on("event", (data) { 64 | //do something here 65 | }); 66 | service.on("stop").listen((event) { 67 | service.stopSelf(); 68 | debugPrint("background process is now stopped"); 69 | }); 70 | 71 | service.on("start").listen((event) {}); 72 | 73 | Timer.periodic(const Duration(seconds: 1), (timer) { 74 | socket.emit("clientData", "hello"); 75 | print("service is successfully running ${DateTime.now().second}"); 76 | }); 77 | } 78 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_background_service_android 2 | description: A flutter plugin for executing dart code continously even application closed. 3 | version: 6.2.7 4 | repository: https://github.com/ekasetiawans/flutter_background_service 5 | 6 | environment: 7 | sdk: ">=2.17.5 <4.0.0" 8 | flutter: ">=3.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | flutter_background_service_platform_interface: ^5.1.2 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://dart.dev/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter. 23 | flutter: 24 | # This section identifies this Flutter project as a plugin project. 25 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 26 | # be modified. They are used by the tooling to maintain consistency when 27 | # adding or updating assets for this project. 28 | plugin: 29 | implements: flutter_background_service 30 | platforms: 31 | android: 32 | package: id.flutter.flutter_background_service 33 | pluginClass: FlutterBackgroundServicePlugin 34 | dartPluginClass: FlutterBackgroundServiceAndroid 35 | # To add assets to your plugin package, add an assets section, like this: 36 | # assets: 37 | # - images/a_dot_burr.jpeg 38 | # - images/a_dot_ham.jpeg 39 | # 40 | # For details regarding assets in packages, see 41 | # https://flutter.dev/assets-and-images/#from-packages 42 | # 43 | # An image asset can refer to one or more resolution-specific "variants", see 44 | # https://flutter.dev/assets-and-images/#resolution-aware. 45 | # To add custom fonts to your plugin package, add a fonts section here, 46 | # in this "flutter" section. Each entry in this list should have a 47 | # "family" key with the font family name, and a "fonts" key with a 48 | # list giving the asset and other descriptors for the font. For 49 | # example: 50 | # fonts: 51 | # - family: Schyler 52 | # fonts: 53 | # - asset: fonts/Schyler-Regular.ttf 54 | # - asset: fonts/Schyler-Italic.ttf 55 | # style: italic 56 | # - family: Trajan Pro 57 | # fonts: 58 | # - asset: fonts/TrajanPro.ttf 59 | # - asset: fonts/TrajanPro_Bold.ttf 60 | # weight: 700 61 | # 62 | # For details regarding fonts in packages, see 63 | # https://flutter.dev/custom-fonts/#from-packages 64 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/lib/src/configs.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter_background_service_platform_interface/flutter_background_service_platform_interface.dart'; 4 | 5 | class IosConfiguration { 6 | /// must be a top level or static method 7 | /// this method will be executed when app is in foreground 8 | final Function(ServiceInstance service)? onForeground; 9 | 10 | /// must be a top level or static method 11 | /// this method will be executed by background fetch 12 | /// make sure you don't execute long running task there because of limitations on ios 13 | /// recommended maximum executed duration is only 15-20 seconds. 14 | final FutureOr Function(ServiceInstance service)? onBackground; 15 | 16 | /// whether service auto start after configure. 17 | final bool autoStart; 18 | 19 | IosConfiguration({ 20 | this.onForeground, 21 | this.onBackground, 22 | this.autoStart = true, 23 | }); 24 | } 25 | 26 | enum AndroidForegroundType { 27 | camera, 28 | connectedDevice, 29 | dataSync, 30 | health, 31 | location, 32 | mediaPlayback, 33 | mediaProjection, 34 | microphone, 35 | phoneCall, 36 | remoteMessaging, 37 | shortService, 38 | specialUse, 39 | systemExempted 40 | } 41 | 42 | class AndroidConfiguration { 43 | /// must be a top level or static method 44 | final Function(ServiceInstance service) onStart; 45 | 46 | /// whether service can start automatically after configure 47 | final bool autoStart; 48 | 49 | /// wheter service can start automatically on boot 50 | final bool autoStartOnBoot; 51 | 52 | /// whether service is foreground or background mode 53 | final bool isForegroundMode; 54 | 55 | /// notification content that will be shown on status bar when the background service is starting 56 | /// defaults to "Preparing" 57 | final String initialNotificationContent; 58 | final String initialNotificationTitle; 59 | 60 | /// use custom notification channel id 61 | /// you must to create the notification channel before you run configure() method. 62 | final String? notificationChannelId; 63 | 64 | /// notification id will be used by foreground service 65 | final int foregroundServiceNotificationId; 66 | 67 | /// foreground service types 68 | final List? foregroundServiceTypes; 69 | 70 | AndroidConfiguration({ 71 | required this.onStart, 72 | this.autoStart = true, 73 | this.autoStartOnBoot = true, 74 | required this.isForegroundMode, 75 | this.initialNotificationContent = 'Preparing', 76 | this.initialNotificationTitle = 'Background Service', 77 | this.notificationChannelId, 78 | this.foregroundServiceNotificationId = 112233, 79 | this.foregroundServiceTypes, 80 | }); 81 | } 82 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/java/id/flutter/flutter_background_service/Config.java: -------------------------------------------------------------------------------- 1 | package id.flutter.flutter_background_service; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | public class Config { 7 | final SharedPreferences pref; 8 | 9 | public Config(Context context) { 10 | this.pref = context.getSharedPreferences("id.flutter.background_service", Context.MODE_PRIVATE); 11 | } 12 | 13 | public boolean isAutoStartOnBoot() { 14 | return pref.getBoolean("auto_start_on_boot", false); 15 | } 16 | 17 | public void setAutoStartOnBoot(boolean value) { 18 | pref.edit() 19 | .putBoolean("auto_start_on_boot", value) 20 | .apply(); 21 | } 22 | 23 | public boolean isForeground() { 24 | return pref.getBoolean("is_foreground", false); 25 | } 26 | 27 | public void setIsForeground(boolean value) { 28 | pref.edit() 29 | .putBoolean("is_foreground", value) 30 | .apply(); 31 | } 32 | 33 | public boolean isManuallyStopped() { 34 | return pref.getBoolean("is_manually_stopped", false); 35 | } 36 | 37 | public void setManuallyStopped(boolean value) { 38 | pref.edit().putBoolean("is_manually_stopped", value).apply(); 39 | } 40 | 41 | public long getBackgroundHandle() { 42 | return pref.getLong("background_handle", 0); 43 | } 44 | 45 | public void setBackgroundHandle(long value) { 46 | pref.edit().putLong("background_handle", value).apply(); 47 | } 48 | 49 | public String getInitialNotificationTitle() { 50 | return pref.getString("initial_notification_title", "Background Service"); 51 | } 52 | 53 | public void setInitialNotificationTitle(String value) { 54 | pref.edit().putString("initial_notification_title", value).apply(); 55 | } 56 | 57 | public String getInitialNotificationContent() { 58 | return pref.getString("initial_notification_content", "Preparing"); 59 | } 60 | 61 | public void setInitialNotificationContent(String value) { 62 | pref.edit().putString("initial_notification_content", value).apply(); 63 | } 64 | 65 | public String getNotificationChannelId() { 66 | return pref.getString("notification_channel_id", null); 67 | } 68 | 69 | public void setNotificationChannelId(String value) { 70 | pref.edit().putString("notification_channel_id", value).apply(); 71 | } 72 | 73 | public int getForegroundNotificationId() { 74 | return pref.getInt("foreground_notification_id", 112233); 75 | } 76 | 77 | public void setForegroundNotificationId(int value) { 78 | pref.edit().putInt("foreground_notification_id", value).apply(); 79 | } 80 | 81 | public String getForegroundServiceTypes() { 82 | return pref.getString("foreground_service_types", null); 83 | } 84 | 85 | public void setForegroundServiceTypes(String value) { 86 | pref.edit().putString("foreground_service_types", value).apply(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #ifdef FLUTTER_BUILD_NUMBER 64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0 67 | #endif 68 | 69 | #ifdef FLUTTER_BUILD_NAME 70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "id.flutter" "\0" 93 | VALUE "FileDescription", "example" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "example" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2022 id.flutter. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "example.exe" "\0" 98 | VALUE "ProductName", "example" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_WIN32_WINDOW_H_ 2 | #define RUNNER_WIN32_WINDOW_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 11 | // inherited from by classes that wish to specialize with custom 12 | // rendering and input handling 13 | class Win32Window { 14 | public: 15 | struct Point { 16 | unsigned int x; 17 | unsigned int y; 18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 19 | }; 20 | 21 | struct Size { 22 | unsigned int width; 23 | unsigned int height; 24 | Size(unsigned int width, unsigned int height) 25 | : width(width), height(height) {} 26 | }; 27 | 28 | Win32Window(); 29 | virtual ~Win32Window(); 30 | 31 | // Creates and shows a win32 window with |title| and position and size using 32 | // |origin| and |size|. New windows are created on the default monitor. Window 33 | // sizes are specified to the OS in physical pixels, hence to ensure a 34 | // consistent size to will treat the width height passed in to this function 35 | // as logical pixels and scale to appropriate for the default monitor. Returns 36 | // true if the window was created successfully. 37 | bool CreateAndShow(const std::wstring& title, 38 | const Point& origin, 39 | const Size& size); 40 | 41 | // Release OS resources associated with window. 42 | void Destroy(); 43 | 44 | // Inserts |content| into the window tree. 45 | void SetChildContent(HWND content); 46 | 47 | // Returns the backing Window handle to enable clients to set icon and other 48 | // window properties. Returns nullptr if the window has been destroyed. 49 | HWND GetHandle(); 50 | 51 | // If true, closing this window will quit the application. 52 | void SetQuitOnClose(bool quit_on_close); 53 | 54 | // Return a RECT representing the bounds of the current client area. 55 | RECT GetClientArea(); 56 | 57 | protected: 58 | // Processes and route salient window messages for mouse handling, 59 | // size change and DPI. Delegates handling of these to member overloads that 60 | // inheriting classes can handle. 61 | virtual LRESULT MessageHandler(HWND window, 62 | UINT const message, 63 | WPARAM const wparam, 64 | LPARAM const lparam) noexcept; 65 | 66 | // Called when CreateAndShow is called, allowing subclass window-related 67 | // setup. Subclasses should return false if setup fails. 68 | virtual bool OnCreate(); 69 | 70 | // Called when Destroy is called. 71 | virtual void OnDestroy(); 72 | 73 | private: 74 | friend class WindowClassRegistrar; 75 | 76 | // OS callback called by message pump. Handles the WM_NCCREATE message which 77 | // is passed when the non-client area is being created and enables automatic 78 | // non-client DPI scaling so that the non-client area automatically 79 | // responsponds to changes in DPI. All other messages are handled by 80 | // MessageHandler. 81 | static LRESULT CALLBACK WndProc(HWND const window, 82 | UINT const message, 83 | WPARAM const wparam, 84 | LPARAM const lparam) noexcept; 85 | 86 | // Retrieves a class instance pointer for |window| 87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 88 | 89 | bool quit_on_close_ = false; 90 | 91 | // window handle for top level window. 92 | HWND window_handle_ = nullptr; 93 | 94 | // window handle for hosted content. 95 | HWND child_content_ = nullptr; 96 | }; 97 | 98 | #endif // RUNNER_WIN32_WINDOW_H_ 99 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(example LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "example") 5 | 6 | cmake_policy(SET CMP0063 NEW) 7 | 8 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 9 | 10 | # Configure build options. 11 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 12 | if(IS_MULTICONFIG) 13 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" 14 | CACHE STRING "" FORCE) 15 | else() 16 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 17 | set(CMAKE_BUILD_TYPE "Debug" CACHE 18 | STRING "Flutter build mode" FORCE) 19 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 20 | "Debug" "Profile" "Release") 21 | endif() 22 | endif() 23 | 24 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") 25 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") 26 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") 27 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") 28 | 29 | # Use Unicode for all projects. 30 | add_definitions(-DUNICODE -D_UNICODE) 31 | 32 | # Compilation settings that should be applied to most targets. 33 | function(APPLY_STANDARD_SETTINGS TARGET) 34 | target_compile_features(${TARGET} PUBLIC cxx_std_17) 35 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") 36 | target_compile_options(${TARGET} PRIVATE /EHsc) 37 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") 38 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") 39 | endfunction() 40 | 41 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 42 | 43 | # Flutter library and tool build rules. 44 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 45 | 46 | # Application build 47 | add_subdirectory("runner") 48 | 49 | # Generated plugin build rules, which manage building the plugins and adding 50 | # them to the application. 51 | include(flutter/generated_plugins.cmake) 52 | 53 | 54 | # === Installation === 55 | # Support files are copied into place next to the executable, so that it can 56 | # run in place. This is done instead of making a separate bundle (as on Linux) 57 | # so that building and running from within Visual Studio will work. 58 | set(BUILD_BUNDLE_DIR "$") 59 | # Make the "install" step default, as it's required to run. 60 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) 61 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 62 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 63 | endif() 64 | 65 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 66 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 67 | 68 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 69 | COMPONENT Runtime) 70 | 71 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 72 | COMPONENT Runtime) 73 | 74 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 75 | COMPONENT Runtime) 76 | 77 | if(PLUGIN_BUNDLED_LIBRARIES) 78 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 79 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 80 | COMPONENT Runtime) 81 | endif() 82 | 83 | # Fully re-copy the assets directory on each build to avoid having stale files 84 | # from a previous install. 85 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 86 | install(CODE " 87 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 88 | " COMPONENT Runtime) 89 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 90 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 91 | 92 | # Install the AOT library on non-Debug builds only. 93 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 94 | CONFIGURATIONS Profile;Release 95 | COMPONENT Runtime) 96 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 4 | 5 | # Configuration provided via flutter tool. 6 | include(${EPHEMERAL_DIR}/generated_config.cmake) 7 | 8 | # TODO: Move the rest of this into files in ephemeral. See 9 | # https://github.com/flutter/flutter/issues/57146. 10 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 11 | 12 | # === Flutter Library === 13 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 14 | 15 | # Published to parent scope for install step. 16 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 17 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 18 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 19 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 20 | 21 | list(APPEND FLUTTER_LIBRARY_HEADERS 22 | "flutter_export.h" 23 | "flutter_windows.h" 24 | "flutter_messenger.h" 25 | "flutter_plugin_registrar.h" 26 | "flutter_texture_registrar.h" 27 | ) 28 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 29 | add_library(flutter INTERFACE) 30 | target_include_directories(flutter INTERFACE 31 | "${EPHEMERAL_DIR}" 32 | ) 33 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 34 | add_dependencies(flutter flutter_assemble) 35 | 36 | # === Wrapper === 37 | list(APPEND CPP_WRAPPER_SOURCES_CORE 38 | "core_implementations.cc" 39 | "standard_codec.cc" 40 | ) 41 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 42 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 43 | "plugin_registrar.cc" 44 | ) 45 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 46 | list(APPEND CPP_WRAPPER_SOURCES_APP 47 | "flutter_engine.cc" 48 | "flutter_view_controller.cc" 49 | ) 50 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 51 | 52 | # Wrapper sources needed for a plugin. 53 | add_library(flutter_wrapper_plugin STATIC 54 | ${CPP_WRAPPER_SOURCES_CORE} 55 | ${CPP_WRAPPER_SOURCES_PLUGIN} 56 | ) 57 | apply_standard_settings(flutter_wrapper_plugin) 58 | set_target_properties(flutter_wrapper_plugin PROPERTIES 59 | POSITION_INDEPENDENT_CODE ON) 60 | set_target_properties(flutter_wrapper_plugin PROPERTIES 61 | CXX_VISIBILITY_PRESET hidden) 62 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 63 | target_include_directories(flutter_wrapper_plugin PUBLIC 64 | "${WRAPPER_ROOT}/include" 65 | ) 66 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 67 | 68 | # Wrapper sources needed for the runner. 69 | add_library(flutter_wrapper_app STATIC 70 | ${CPP_WRAPPER_SOURCES_CORE} 71 | ${CPP_WRAPPER_SOURCES_APP} 72 | ) 73 | apply_standard_settings(flutter_wrapper_app) 74 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 75 | target_include_directories(flutter_wrapper_app PUBLIC 76 | "${WRAPPER_ROOT}/include" 77 | ) 78 | add_dependencies(flutter_wrapper_app flutter_assemble) 79 | 80 | # === Flutter tool backend === 81 | # _phony_ is a non-existent file to force this command to run every time, 82 | # since currently there's no way to get a full input/output list from the 83 | # flutter tool. 84 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") 85 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) 86 | add_custom_command( 87 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 88 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 89 | ${CPP_WRAPPER_SOURCES_APP} 90 | ${PHONY_OUTPUT} 91 | COMMAND ${CMAKE_COMMAND} -E env 92 | ${FLUTTER_TOOL_ENVIRONMENT} 93 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 94 | windows-x64 $ 95 | VERBATIM 96 | ) 97 | add_custom_target(flutter_assemble DEPENDS 98 | "${FLUTTER_LIBRARY}" 99 | ${FLUTTER_LIBRARY_HEADERS} 100 | ${CPP_WRAPPER_SOURCES_CORE} 101 | ${CPP_WRAPPER_SOURCES_PLUGIN} 102 | ${CPP_WRAPPER_SOURCES_APP} 103 | ) 104 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/java/id/flutter/flutter_background_service/WatchdogReceiver.java: -------------------------------------------------------------------------------- 1 | package id.flutter.flutter_background_service; 2 | 3 | import static android.content.Context.ALARM_SERVICE; 4 | import static android.os.Build.VERSION.SDK_INT; 5 | 6 | import android.app.AlarmManager; 7 | import android.app.PendingIntent; 8 | import android.content.BroadcastReceiver; 9 | import android.app.ActivityManager; 10 | import android.content.Context; 11 | import android.content.Intent; 12 | import android.os.Build; 13 | 14 | import androidx.core.app.AlarmManagerCompat; 15 | import androidx.core.content.ContextCompat; 16 | 17 | public class WatchdogReceiver extends BroadcastReceiver { 18 | private static final int QUEUE_REQUEST_ID = 111; 19 | private static final String ACTION_RESPAWN = "id.flutter.background_service.RESPAWN"; 20 | 21 | public static void enqueue(Context context) { 22 | enqueue(context, 5000); 23 | } 24 | 25 | public static void enqueue(Context context, int millis) { 26 | Intent intent = new Intent(context, WatchdogReceiver.class); 27 | intent.setAction(ACTION_RESPAWN); 28 | AlarmManager manager = (AlarmManager) context.getSystemService(ALARM_SERVICE); 29 | 30 | int flags = PendingIntent.FLAG_UPDATE_CURRENT; 31 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 32 | flags |= PendingIntent.FLAG_MUTABLE; 33 | } 34 | 35 | PendingIntent pIntent = PendingIntent.getBroadcast(context, QUEUE_REQUEST_ID, intent, flags); 36 | 37 | // Check is background service every 5 seconds 38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 39 | // Android 13 (SDK 33) requires apps to declare android.permission.SCHEDULE_EXACT_ALARM to use setExact 40 | // Android 14 (SDK 34) takes this further and requires that apps explicitly ask for user permission before 41 | // using setExact. 42 | // On these versions, use setAndAllowWhileIdle instead - it is _almost_ the same, but allows the OS to delay 43 | // the alarm a bit to minimize device wake-ups 44 | AlarmManagerCompat.setAndAllowWhileIdle(manager, AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + millis, pIntent); 45 | } else { 46 | AlarmManagerCompat.setExact(manager, AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + millis, pIntent); 47 | } 48 | } 49 | 50 | public static void remove(Context context) { 51 | Intent intent = new Intent(context, WatchdogReceiver.class); 52 | intent.setAction(ACTION_RESPAWN); 53 | 54 | int flags = PendingIntent.FLAG_CANCEL_CURRENT; 55 | if (SDK_INT >= Build.VERSION_CODES.S) { 56 | flags |= PendingIntent.FLAG_MUTABLE; 57 | } 58 | 59 | PendingIntent pi = PendingIntent.getBroadcast(context, WatchdogReceiver.QUEUE_REQUEST_ID, intent, flags); 60 | AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE); 61 | alarmManager.cancel(pi); 62 | } 63 | 64 | @Override 65 | public void onReceive(Context context, Intent intent) { 66 | if (intent.getAction().equals(ACTION_RESPAWN)) { 67 | final Config config = new Config(context); 68 | boolean isRunning = false; 69 | 70 | ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 71 | for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 72 | if (BackgroundService.class.getName().equals(service.service.getClassName())) { 73 | isRunning = true; 74 | } 75 | } 76 | 77 | if (!config.isManuallyStopped() && !isRunning) { 78 | try { 79 | if (config.isForeground()) { 80 | ContextCompat.startForegroundService(context, new Intent(context, id.flutter.flutter_background_service.BackgroundService.class)); 81 | } else { 82 | context.getApplicationContext().startService(new Intent(context, id.flutter.flutter_background_service.BackgroundService.class)); 83 | }} 84 | catch (Exception e){ 85 | e.printStackTrace(); 86 | } 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | example 33 | 34 | 35 | 36 | 39 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 2.0.0 19 | 20 | environment: 21 | sdk: ">=2.17.5 <4.0.0" 22 | 23 | # Dependencies specify other packages that your package needs in order to work. 24 | # To automatically upgrade your package dependencies to the latest versions 25 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 26 | # dependencies can be manually updated by changing the version numbers below to 27 | # the latest version available on pub.dev. To see which dependencies have newer 28 | # versions available, run `flutter pub outdated`. 29 | dependencies: 30 | flutter: 31 | sdk: flutter 32 | 33 | flutter_background_service: 34 | # When depending on this package from a real application you should use: 35 | # flutter_background_service: ^x.y.z 36 | # See https://dart.dev/tools/pub/dependencies#version-constraints 37 | # The example app is bundled with the plugin so we use a path dependency on 38 | # the parent directory to use the current plugin's version. 39 | path: ../ 40 | 41 | flutter_background_service_ios: ^5.0.3 42 | flutter_background_service_android: ^6.2.7 43 | # The following adds the Cupertino Icons font to your application. 44 | # Use with the CupertinoIcons class for iOS style icons. 45 | cupertino_icons: ^1.0.5 46 | device_info_plus: ^9.0.2 47 | shared_preferences: ^2.1.2 48 | 49 | # optional if you wish to use a custom foreground service notification 50 | flutter_local_notifications: ^14.1.1 51 | 52 | dev_dependencies: 53 | flutter_test: 54 | sdk: flutter 55 | 56 | # The "flutter_lints" package below contains a set of recommended lints to 57 | # encourage good coding practices. The lint set provided by the package is 58 | # activated in the `analysis_options.yaml` file located at the root of your 59 | # package. See that file for information about deactivating specific lint 60 | # rules and activating additional ones. 61 | flutter_lints: ^2.0.1 62 | 63 | # For information on the generic Dart part of this file, see the 64 | # following page: https://dart.dev/tools/pub/pubspec 65 | 66 | # The following section is specific to Flutter. 67 | flutter: 68 | # The following line ensures that the Material Icons font is 69 | # included with your application, so that you can use the icons in 70 | # the material Icons class. 71 | uses-material-design: true 72 | 73 | # To add assets to your application, add an assets section, like this: 74 | # assets: 75 | # - images/a_dot_burr.jpeg 76 | # - images/a_dot_ham.jpeg 77 | 78 | # An image asset can refer to one or more resolution-specific "variants", see 79 | # https://flutter.dev/assets-and-images/#resolution-aware. 80 | 81 | # For details regarding adding assets from package dependencies, see 82 | # https://flutter.dev/assets-and-images/#from-packages 83 | 84 | # To add custom fonts to your application, add a fonts section here, 85 | # in this "flutter" section. Each entry in this list should have a 86 | # "family" key with the font family name, and a "fonts" key with a 87 | # list giving the asset and other descriptors for the font. For 88 | # example: 89 | # fonts: 90 | # - family: Schyler 91 | # fonts: 92 | # - asset: fonts/Schyler-Regular.ttf 93 | # - asset: fonts/Schyler-Italic.ttf 94 | # style: italic 95 | # - family: Trajan Pro 96 | # fonts: 97 | # - asset: fonts/TrajanPro.ttf 98 | # - asset: fonts/TrajanPro_Bold.ttf 99 | # weight: 700 100 | # 101 | # For details regarding fonts from package dependencies, 102 | # see https://flutter.dev/custom-fonts/#from-packages 103 | -------------------------------------------------------------------------------- /packages/flutter_background_service_ios/lib/flutter_background_service_ios.dart: -------------------------------------------------------------------------------- 1 | library flutter_background_service_ios; 2 | 3 | import 'dart:async'; 4 | import 'dart:ui'; 5 | 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter/services.dart'; 8 | import 'package:flutter_background_service_platform_interface/flutter_background_service_platform_interface.dart'; 9 | 10 | @pragma('vm:entry-point') 11 | Future foregroundEntrypoint(List args) async { 12 | WidgetsFlutterBinding.ensureInitialized(); 13 | final service = IOSServiceInstance._(); 14 | final int handle = int.parse(args.first); 15 | final callbackHandle = CallbackHandle.fromRawHandle(handle); 16 | final onStart = PluginUtilities.getCallbackFromHandle(callbackHandle); 17 | if (onStart != null) { 18 | onStart(service); 19 | } 20 | } 21 | 22 | @pragma('vm:entry-point') 23 | Future backgroundEntrypoint(List args) async { 24 | WidgetsFlutterBinding.ensureInitialized(); 25 | final service = IOSServiceInstance._(); 26 | final int handle = int.parse(args.first); 27 | final callbackHandle = CallbackHandle.fromRawHandle(handle); 28 | final onStart = PluginUtilities.getCallbackFromHandle(callbackHandle) 29 | as FutureOr Function(ServiceInstance instance)?; 30 | if (onStart != null) { 31 | final result = await onStart(service); 32 | await service._setBackgroundFetchResult(result); 33 | } 34 | } 35 | 36 | class FlutterBackgroundServiceIOS extends FlutterBackgroundServicePlatform { 37 | /// Registers this class as the default instance of [FlutterBackgroundServicePlatform]. 38 | static void registerWith() { 39 | FlutterBackgroundServicePlatform.instance = FlutterBackgroundServiceIOS(); 40 | } 41 | 42 | static const MethodChannel _channel = const MethodChannel( 43 | 'id.flutter/background_service_ios', 44 | JSONMethodCodec(), 45 | ); 46 | 47 | Future _handle(MethodCall call) async { 48 | switch (call.method) { 49 | case "onReceiveData": 50 | _streamController.sink.add(call.arguments); 51 | break; 52 | default: 53 | } 54 | 55 | return true; 56 | } 57 | 58 | Future start() async { 59 | final result = await _channel.invokeMethod('start'); 60 | return result ?? false; 61 | } 62 | 63 | Future configure({ 64 | required IosConfiguration iosConfiguration, 65 | required AndroidConfiguration androidConfiguration, 66 | }) async { 67 | _channel.setMethodCallHandler(_handle); 68 | 69 | final CallbackHandle? foregroundHandle = 70 | iosConfiguration.onForeground == null 71 | ? null 72 | : PluginUtilities.getCallbackHandle(iosConfiguration.onForeground!); 73 | 74 | final CallbackHandle? backgroundHandle = 75 | iosConfiguration.onBackground == null 76 | ? null 77 | : PluginUtilities.getCallbackHandle(iosConfiguration.onBackground!); 78 | 79 | final result = await _channel.invokeMethod( 80 | "configure", 81 | { 82 | "background_handle": backgroundHandle?.toRawHandle(), 83 | "foreground_handle": foregroundHandle?.toRawHandle(), 84 | "auto_start": iosConfiguration.autoStart, 85 | }, 86 | ); 87 | 88 | return result ?? false; 89 | } 90 | 91 | Future isServiceRunning() async { 92 | var result = await _channel.invokeMethod("isServiceRunning"); 93 | return result ?? false; 94 | } 95 | 96 | final _streamController = StreamController.broadcast(sync: true); 97 | 98 | void dispose() { 99 | _streamController.close(); 100 | } 101 | 102 | @override 103 | void invoke(String method, [Map? args]) { 104 | _channel.invokeMethod("sendData", { 105 | 'method': method, 106 | 'args': args, 107 | }); 108 | } 109 | 110 | @override 111 | Stream?> on(String method) { 112 | return _streamController.stream.transform( 113 | StreamTransformer.fromHandlers( 114 | handleData: (data, sink) { 115 | if (data['method'] == method) { 116 | sink.add(data['args']); 117 | } 118 | }, 119 | ), 120 | ); 121 | } 122 | } 123 | 124 | class IOSServiceInstance extends ServiceInstance { 125 | static const MethodChannel _channel = const MethodChannel( 126 | 'id.flutter/background_service_ios_bg', 127 | JSONMethodCodec(), 128 | ); 129 | 130 | IOSServiceInstance._() { 131 | _channel.setMethodCallHandler(_handleMethodCall); 132 | } 133 | 134 | final _controller = StreamController.broadcast(sync: true); 135 | Future _handleMethodCall(MethodCall call) async { 136 | switch (call.method) { 137 | case "onReceiveData": 138 | _controller.sink.add(call.arguments); 139 | break; 140 | default: 141 | } 142 | } 143 | 144 | @override 145 | void invoke(String method, [Map? args]) { 146 | _channel.invokeMethod('sendData', { 147 | 'method': method, 148 | 'args': args, 149 | }); 150 | } 151 | 152 | @override 153 | Future stopSelf() async { 154 | await _channel.invokeMethod("stopService"); 155 | } 156 | 157 | @override 158 | Stream?> on(String method) { 159 | return _controller.stream.transform( 160 | StreamTransformer.fromHandlers( 161 | handleData: (data, sink) { 162 | if (data['method'] == method) { 163 | sink.add(data['args']); 164 | } 165 | }, 166 | ), 167 | ); 168 | } 169 | 170 | Future _setBackgroundFetchResult(bool value) async { 171 | await _channel.invokeMethod('setBackgroundFetchResult', value); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/lib/flutter_background_service_android.dart: -------------------------------------------------------------------------------- 1 | library flutter_background_service_android; 2 | 3 | import 'dart:async'; 4 | import 'dart:ui'; 5 | 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter/services.dart'; 8 | import 'package:flutter_background_service_platform_interface/flutter_background_service_platform_interface.dart'; 9 | 10 | bool _isMainIsolate = true; 11 | 12 | @pragma('vm:entry-point') 13 | Future entrypoint(List args) async { 14 | WidgetsFlutterBinding.ensureInitialized(); 15 | _isMainIsolate = false; 16 | 17 | final service = AndroidServiceInstance._(); 18 | final int handle = int.parse(args.first); 19 | final callbackHandle = CallbackHandle.fromRawHandle(handle); 20 | final onStart = PluginUtilities.getCallbackFromHandle(callbackHandle); 21 | if (onStart != null) { 22 | onStart(service); 23 | } 24 | } 25 | 26 | class FlutterBackgroundServiceAndroid extends FlutterBackgroundServicePlatform { 27 | /// Registers this class as the default instance of [FlutterBackgroundServicePlatform]. 28 | static void registerWith() { 29 | FlutterBackgroundServicePlatform.instance = 30 | FlutterBackgroundServiceAndroid(); 31 | } 32 | 33 | FlutterBackgroundServiceAndroid._(); 34 | static final FlutterBackgroundServiceAndroid _instance = 35 | FlutterBackgroundServiceAndroid._(); 36 | 37 | factory FlutterBackgroundServiceAndroid() { 38 | if (!_isMainIsolate) { 39 | throw Exception( 40 | "This class should only be used in the main isolate (UI App)", 41 | ); 42 | } 43 | 44 | return _instance; 45 | } 46 | 47 | Future _handleMethodCall(MethodCall call) async { 48 | debugPrint(call.method); 49 | 50 | switch (call.method) { 51 | case "onReceiveData": 52 | _controller.sink.add(call.arguments); 53 | break; 54 | default: 55 | } 56 | } 57 | 58 | Future start() async { 59 | final result = await _channel.invokeMethod('start'); 60 | return result ?? false; 61 | } 62 | 63 | final MethodChannel _channel = MethodChannel( 64 | 'id.flutter/background_service/android/method', 65 | JSONMethodCodec(), 66 | ); 67 | 68 | final EventChannel _eventChannel = EventChannel( 69 | 'id.flutter/background_service/android/event', 70 | JSONMethodCodec(), 71 | ); 72 | 73 | StreamSubscription? _eventChannelListener; 74 | Future configure({ 75 | required IosConfiguration iosConfiguration, 76 | required AndroidConfiguration androidConfiguration, 77 | }) async { 78 | _channel.setMethodCallHandler(_handleMethodCall); 79 | 80 | _eventChannelListener?.cancel(); 81 | _eventChannelListener = 82 | _eventChannel.receiveBroadcastStream().listen((event) { 83 | _controller.sink.add(event); 84 | }); 85 | 86 | final CallbackHandle? handle = 87 | PluginUtilities.getCallbackHandle(androidConfiguration.onStart); 88 | 89 | if (handle == null) { 90 | throw 'onStart method must be a top-level or static function'; 91 | } 92 | 93 | List? configForegroundServiceTypes = 94 | androidConfiguration.foregroundServiceTypes; 95 | List? foregroundServiceTypes; 96 | if (configForegroundServiceTypes != null && 97 | configForegroundServiceTypes.length > 0) { 98 | foregroundServiceTypes = []; 99 | androidConfiguration.foregroundServiceTypes! 100 | .forEach((foregroundServiceType) { 101 | foregroundServiceTypes!.add(foregroundServiceType.name); 102 | }); 103 | } 104 | 105 | final result = await _channel.invokeMethod( 106 | "configure", 107 | { 108 | "background_handle": handle.toRawHandle(), 109 | "is_foreground_mode": androidConfiguration.isForegroundMode, 110 | "auto_start": androidConfiguration.autoStart, 111 | "auto_start_on_boot": androidConfiguration.autoStartOnBoot, 112 | "initial_notification_content": 113 | androidConfiguration.initialNotificationContent, 114 | "initial_notification_title": 115 | androidConfiguration.initialNotificationTitle, 116 | "notification_channel_id": androidConfiguration.notificationChannelId, 117 | "foreground_notification_id": 118 | androidConfiguration.foregroundServiceNotificationId, 119 | "foreground_service_types": foregroundServiceTypes, 120 | }, 121 | ); 122 | 123 | return result ?? false; 124 | } 125 | 126 | Future isServiceRunning() async { 127 | var result = await _channel.invokeMethod("isServiceRunning"); 128 | return result ?? false; 129 | } 130 | 131 | final _controller = StreamController.broadcast(sync: true); 132 | 133 | void dispose() { 134 | _controller.close(); 135 | } 136 | 137 | @override 138 | void invoke(String method, [Map? args]) { 139 | _channel.invokeMethod("sendData", { 140 | 'method': method, 141 | 'args': args, 142 | }); 143 | } 144 | 145 | @override 146 | Stream?> on(String method) { 147 | return _controller.stream.transform( 148 | StreamTransformer.fromHandlers( 149 | handleData: (data, sink) { 150 | if (data['method'] == method) { 151 | sink.add(data['args']); 152 | } 153 | }, 154 | ), 155 | ); 156 | } 157 | } 158 | 159 | class AndroidServiceInstance extends ServiceInstance { 160 | static const MethodChannel _channel = const MethodChannel( 161 | 'id.flutter/background_service_android_bg', 162 | JSONMethodCodec(), 163 | ); 164 | 165 | AndroidServiceInstance._() { 166 | _channel.setMethodCallHandler(_handleMethodCall); 167 | } 168 | 169 | final _controller = StreamController.broadcast(sync: true); 170 | Future _handleMethodCall(MethodCall call) async { 171 | switch (call.method) { 172 | case "onReceiveData": 173 | _controller.sink.add(call.arguments); 174 | break; 175 | default: 176 | } 177 | } 178 | 179 | @override 180 | void invoke(String method, [Map? args]) { 181 | _channel.invokeMethod('sendData', { 182 | 'method': method, 183 | 'args': args, 184 | }); 185 | } 186 | 187 | @override 188 | Future stopSelf() async { 189 | await _channel.invokeMethod("stopService"); 190 | } 191 | 192 | @override 193 | Stream?> on(String method) { 194 | return _controller.stream.transform( 195 | StreamTransformer.fromHandlers( 196 | handleData: (data, sink) { 197 | if (data['method'] == method) { 198 | sink.add(data['args']); 199 | } 200 | }, 201 | ), 202 | ); 203 | } 204 | 205 | Future setForegroundNotificationInfo({ 206 | required String title, 207 | required String content, 208 | }) async { 209 | await _channel.invokeMethod("setNotificationInfo", { 210 | "title": title, 211 | "content": content, 212 | }); 213 | } 214 | 215 | Future setAsForegroundService() async { 216 | await _channel.invokeMethod("setForegroundMode", { 217 | 'value': true, 218 | }); 219 | } 220 | 221 | Future setAsBackgroundService() async { 222 | await _channel.invokeMethod("setForegroundMode", { 223 | 'value': false, 224 | }); 225 | } 226 | 227 | /// returns true when the current Service instance is in foreground mode. 228 | Future isForegroundService() async { 229 | final result = await _channel.invokeMethod('isForegroundMode'); 230 | return result ?? false; 231 | } 232 | 233 | Future setAutoStartOnBootMode(bool value) async { 234 | await _channel.invokeMethod("setAutoStartOnBootMode", { 235 | "value": value, 236 | }); 237 | } 238 | 239 | Future openApp() async { 240 | final result = await _channel.invokeMethod('openApp'); 241 | return result ?? false; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /packages/flutter_background_service_platform_interface/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 5.1.2 2 | 3 | - **FIX**: fix lints. ([95186405](https://github.com/ekasetiawans/flutter_background_service/commit/95186405f2d60112ff83956bce345ebbbc332ad7)) 4 | 5 | ## 5.1.1 6 | 7 | - **FIX**: fix crash on android 14 after starting foreground service. ([4bdc46d9](https://github.com/ekasetiawans/flutter_background_service/commit/4bdc46d951febafbcbb2b118324cddc2b30ad752)) 8 | 9 | ## 5.1.0 10 | 11 | - **FEAT**: updated dependencies. ([e90ad787](https://github.com/ekasetiawans/flutter_background_service/commit/e90ad787b3a7b157aeeec3a45920839aafe2933d)) 12 | 13 | ## 5.0.0 14 | 15 | > Note: This release has breaking changes. 16 | 17 | - **REFACTOR**: refactor java code. ([d7db0c09](https://github.com/ekasetiawans/flutter_background_service/commit/d7db0c092dcfc0af0bb8f1175ea82f3f0ccfe908)) 18 | - **REFACTOR**: initialize melos. ([00bf06da](https://github.com/ekasetiawans/flutter_background_service/commit/00bf06da1ca1f4554edaabbd108c59f34b02c611)) 19 | - **FIX**: remove duplicated properties. ([891c2029](https://github.com/ekasetiawans/flutter_background_service/commit/891c20291df9612810035219af98d732d99d200c)) 20 | - **FIX**: missing foregroundServiceNotificationId. ([e49f6137](https://github.com/ekasetiawans/flutter_background_service/commit/e49f613726120f144b04e2246c43360756d57e5b)) 21 | - **FIX**: errors. ([13a6f841](https://github.com/ekasetiawans/flutter_background_service/commit/13a6f841f5d677ceb0010e8ba1bf9d7af53adbcf)) 22 | - **FIX**: method channel. ([1a1e3527](https://github.com/ekasetiawans/flutter_background_service/commit/1a1e3527465a4ede4c188b4e1aa51ce552e697c1)) 23 | - **FEAT**: Updated configs. ([7af1961d](https://github.com/ekasetiawans/flutter_background_service/commit/7af1961def1625d7a5314812c1f794e327f53ce7)) 24 | - **FEAT**: using entrypoint instead of dart callback and added initial notification info for android. ([b0fc8f32](https://github.com/ekasetiawans/flutter_background_service/commit/b0fc8f32d59fa582c37fcd6e2349fab32aac245b)) 25 | - **DOCS**: update license. ([0c17e5de](https://github.com/ekasetiawans/flutter_background_service/commit/0c17e5dee091daa622470c8e3ba16c22ae03f8b3)) 26 | - **DOCS**: readme link. ([1479b91c](https://github.com/ekasetiawans/flutter_background_service/commit/1479b91cd80d637335de1314a528bcf51ebb7c0f)) 27 | - **DOCS**: update README. ([fbf5e0ab](https://github.com/ekasetiawans/flutter_background_service/commit/fbf5e0abeeb9296ba32361b8af0a298ee9e71527)) 28 | - **BREAKING** **FEAT**: updated dependency constraints. ([97ef7977](https://github.com/ekasetiawans/flutter_background_service/commit/97ef7977ff9a2cb31b1e29593b3a9cc725d89e27)) 29 | - **BREAKING** **FEAT**: introduce ServiceInstance. ([425279b0](https://github.com/ekasetiawans/flutter_background_service/commit/425279b09378fbcd8e66295ce526f2c4f15d741c)) 30 | - **BREAKING** **CHANGE**: supported only flutter 2.0.0 and newer. ([be0c32f8](https://github.com/ekasetiawans/flutter_background_service/commit/be0c32f8200dcce44ddce67461c333d6d0ef287c)) 31 | 32 | ## 4.0.0 33 | 34 | > Note: This release has breaking changes. 35 | 36 | - **REFACTOR**: refactor java code. ([d7db0c09](https://github.com/ekasetiawans/flutter_background_service/commit/d7db0c092dcfc0af0bb8f1175ea82f3f0ccfe908)) 37 | - **REFACTOR**: initialize melos. ([00bf06da](https://github.com/ekasetiawans/flutter_background_service/commit/00bf06da1ca1f4554edaabbd108c59f34b02c611)) 38 | - **FIX**: remove duplicated properties. ([891c2029](https://github.com/ekasetiawans/flutter_background_service/commit/891c20291df9612810035219af98d732d99d200c)) 39 | - **FIX**: missing foregroundServiceNotificationId. ([e49f6137](https://github.com/ekasetiawans/flutter_background_service/commit/e49f613726120f144b04e2246c43360756d57e5b)) 40 | - **FIX**: errors. ([13a6f841](https://github.com/ekasetiawans/flutter_background_service/commit/13a6f841f5d677ceb0010e8ba1bf9d7af53adbcf)) 41 | - **FIX**: method channel. ([1a1e3527](https://github.com/ekasetiawans/flutter_background_service/commit/1a1e3527465a4ede4c188b4e1aa51ce552e697c1)) 42 | - **FEAT**: Updated configs. ([7af1961d](https://github.com/ekasetiawans/flutter_background_service/commit/7af1961def1625d7a5314812c1f794e327f53ce7)) 43 | - **FEAT**: using entrypoint instead of dart callback and added initial notification info for android. ([b0fc8f32](https://github.com/ekasetiawans/flutter_background_service/commit/b0fc8f32d59fa582c37fcd6e2349fab32aac245b)) 44 | - **DOCS**: update license. ([0c17e5de](https://github.com/ekasetiawans/flutter_background_service/commit/0c17e5dee091daa622470c8e3ba16c22ae03f8b3)) 45 | - **DOCS**: readme link. ([1479b91c](https://github.com/ekasetiawans/flutter_background_service/commit/1479b91cd80d637335de1314a528bcf51ebb7c0f)) 46 | - **DOCS**: update README. ([fbf5e0ab](https://github.com/ekasetiawans/flutter_background_service/commit/fbf5e0abeeb9296ba32361b8af0a298ee9e71527)) 47 | - **BREAKING** **FEAT**: updated dependency constraints. ([97ef7977](https://github.com/ekasetiawans/flutter_background_service/commit/97ef7977ff9a2cb31b1e29593b3a9cc725d89e27)) 48 | - **BREAKING** **FEAT**: introduce ServiceInstance. ([425279b0](https://github.com/ekasetiawans/flutter_background_service/commit/425279b09378fbcd8e66295ce526f2c4f15d741c)) 49 | - **BREAKING** **CHANGE**: supported only flutter 2.0.0 and newer. ([be0c32f8](https://github.com/ekasetiawans/flutter_background_service/commit/be0c32f8200dcce44ddce67461c333d6d0ef287c)) 50 | 51 | ## 3.0.0 52 | 53 | > Note: This release has breaking changes. 54 | 55 | - **BREAKING** **FEAT**: updated dependency constraints. ([97ef7977](https://github.com/ekasetiawans/flutter_background_service/commit/97ef7977ff9a2cb31b1e29593b3a9cc725d89e27)) 56 | 57 | ## 2.2.0 58 | 59 | - **FEAT**: Updated configs. ([7af1961d](https://github.com/ekasetiawans/flutter_background_service/commit/7af1961def1625d7a5314812c1f794e327f53ce7)) 60 | 61 | ## 2.1.4 62 | 63 | - **REFACTOR**: refactor java code. ([d7db0c09](https://github.com/ekasetiawans/flutter_background_service/commit/d7db0c092dcfc0af0bb8f1175ea82f3f0ccfe908)) 64 | 65 | ## 2.1.3 66 | 67 | - **DOCS**: update license. ([0c17e5de](https://github.com/ekasetiawans/flutter_background_service/commit/0c17e5dee091daa622470c8e3ba16c22ae03f8b3)) 68 | 69 | ## 2.1.2 70 | 71 | - **FIX**: remove duplicated properties. ([891c2029](https://github.com/ekasetiawans/flutter_background_service/commit/891c20291df9612810035219af98d732d99d200c)) 72 | 73 | ## 2.1.1 74 | 75 | - **FIX**: missing foregroundServiceNotificationId. ([e49f6137](https://github.com/ekasetiawans/flutter_background_service/commit/e49f613726120f144b04e2246c43360756d57e5b)) 76 | 77 | ## 2.1.0 78 | 79 | - **FEAT**: using entrypoint instead of dart callback and added initial notification info for android. ([b0fc8f32](https://github.com/ekasetiawans/flutter_background_service/commit/b0fc8f32d59fa582c37fcd6e2349fab32aac245b)) 80 | 81 | ## 2.0.0 82 | 83 | - Graduate package to a stable release. See pre-releases prior to this version for changelog entries. 84 | 85 | ## 2.0.0-dev.0 86 | 87 | > Note: This release has breaking changes. 88 | 89 | - **BREAKING** **FEAT**: introduce ServiceInstance. ([425279b0](https://github.com/ekasetiawans/flutter_background_service/commit/425279b09378fbcd8e66295ce526f2c4f15d741c)) 90 | 91 | ## 1.0.2 92 | 93 | - **DOCS**: readme link. ([1479b91c](https://github.com/ekasetiawans/flutter_background_service/commit/1479b91cd80d637335de1314a528bcf51ebb7c0f)) 94 | 95 | ## 1.0.1 96 | 97 | - **DOCS**: update README. ([fbf5e0ab](https://github.com/ekasetiawans/flutter_background_service/commit/fbf5e0abeeb9296ba32361b8af0a298ee9e71527)) 98 | 99 | ## 0.0.1+3 100 | 101 | - **FIX**: errors. ([13a6f841](https://github.com/ekasetiawans/flutter_background_service/commit/13a6f841f5d677ceb0010e8ba1bf9d7af53adbcf)) 102 | 103 | ## 0.0.1+2 104 | 105 | - **FIX**: method channel. ([1a1e3527](https://github.com/ekasetiawans/flutter_background_service/commit/1a1e3527465a4ede4c188b4e1aa51ce552e697c1)) 106 | 107 | ## 0.0.1+1 108 | 109 | - **REFACTOR**: initialize melos. 110 | 111 | ## 0.0.1 112 | 113 | * Initial release 114 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/windows/runner/win32_window.cpp: -------------------------------------------------------------------------------- 1 | #include "win32_window.h" 2 | 3 | #include 4 | 5 | #include "resource.h" 6 | 7 | namespace { 8 | 9 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; 10 | 11 | // The number of Win32Window objects that currently exist. 12 | static int g_active_window_count = 0; 13 | 14 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); 15 | 16 | // Scale helper to convert logical scaler values to physical using passed in 17 | // scale factor 18 | int Scale(int source, double scale_factor) { 19 | return static_cast(source * scale_factor); 20 | } 21 | 22 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. 23 | // This API is only needed for PerMonitor V1 awareness mode. 24 | void EnableFullDpiSupportIfAvailable(HWND hwnd) { 25 | HMODULE user32_module = LoadLibraryA("User32.dll"); 26 | if (!user32_module) { 27 | return; 28 | } 29 | auto enable_non_client_dpi_scaling = 30 | reinterpret_cast( 31 | GetProcAddress(user32_module, "EnableNonClientDpiScaling")); 32 | if (enable_non_client_dpi_scaling != nullptr) { 33 | enable_non_client_dpi_scaling(hwnd); 34 | FreeLibrary(user32_module); 35 | } 36 | } 37 | 38 | } // namespace 39 | 40 | // Manages the Win32Window's window class registration. 41 | class WindowClassRegistrar { 42 | public: 43 | ~WindowClassRegistrar() = default; 44 | 45 | // Returns the singleton registar instance. 46 | static WindowClassRegistrar* GetInstance() { 47 | if (!instance_) { 48 | instance_ = new WindowClassRegistrar(); 49 | } 50 | return instance_; 51 | } 52 | 53 | // Returns the name of the window class, registering the class if it hasn't 54 | // previously been registered. 55 | const wchar_t* GetWindowClass(); 56 | 57 | // Unregisters the window class. Should only be called if there are no 58 | // instances of the window. 59 | void UnregisterWindowClass(); 60 | 61 | private: 62 | WindowClassRegistrar() = default; 63 | 64 | static WindowClassRegistrar* instance_; 65 | 66 | bool class_registered_ = false; 67 | }; 68 | 69 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; 70 | 71 | const wchar_t* WindowClassRegistrar::GetWindowClass() { 72 | if (!class_registered_) { 73 | WNDCLASS window_class{}; 74 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); 75 | window_class.lpszClassName = kWindowClassName; 76 | window_class.style = CS_HREDRAW | CS_VREDRAW; 77 | window_class.cbClsExtra = 0; 78 | window_class.cbWndExtra = 0; 79 | window_class.hInstance = GetModuleHandle(nullptr); 80 | window_class.hIcon = 81 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 82 | window_class.hbrBackground = 0; 83 | window_class.lpszMenuName = nullptr; 84 | window_class.lpfnWndProc = Win32Window::WndProc; 85 | RegisterClass(&window_class); 86 | class_registered_ = true; 87 | } 88 | return kWindowClassName; 89 | } 90 | 91 | void WindowClassRegistrar::UnregisterWindowClass() { 92 | UnregisterClass(kWindowClassName, nullptr); 93 | class_registered_ = false; 94 | } 95 | 96 | Win32Window::Win32Window() { 97 | ++g_active_window_count; 98 | } 99 | 100 | Win32Window::~Win32Window() { 101 | --g_active_window_count; 102 | Destroy(); 103 | } 104 | 105 | bool Win32Window::CreateAndShow(const std::wstring& title, 106 | const Point& origin, 107 | const Size& size) { 108 | Destroy(); 109 | 110 | const wchar_t* window_class = 111 | WindowClassRegistrar::GetInstance()->GetWindowClass(); 112 | 113 | const POINT target_point = {static_cast(origin.x), 114 | static_cast(origin.y)}; 115 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); 116 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); 117 | double scale_factor = dpi / 96.0; 118 | 119 | HWND window = CreateWindow( 120 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 121 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), 122 | Scale(size.width, scale_factor), Scale(size.height, scale_factor), 123 | nullptr, nullptr, GetModuleHandle(nullptr), this); 124 | 125 | if (!window) { 126 | return false; 127 | } 128 | 129 | return OnCreate(); 130 | } 131 | 132 | // static 133 | LRESULT CALLBACK Win32Window::WndProc(HWND const window, 134 | UINT const message, 135 | WPARAM const wparam, 136 | LPARAM const lparam) noexcept { 137 | if (message == WM_NCCREATE) { 138 | auto window_struct = reinterpret_cast(lparam); 139 | SetWindowLongPtr(window, GWLP_USERDATA, 140 | reinterpret_cast(window_struct->lpCreateParams)); 141 | 142 | auto that = static_cast(window_struct->lpCreateParams); 143 | EnableFullDpiSupportIfAvailable(window); 144 | that->window_handle_ = window; 145 | } else if (Win32Window* that = GetThisFromHandle(window)) { 146 | return that->MessageHandler(window, message, wparam, lparam); 147 | } 148 | 149 | return DefWindowProc(window, message, wparam, lparam); 150 | } 151 | 152 | LRESULT 153 | Win32Window::MessageHandler(HWND hwnd, 154 | UINT const message, 155 | WPARAM const wparam, 156 | LPARAM const lparam) noexcept { 157 | switch (message) { 158 | case WM_DESTROY: 159 | window_handle_ = nullptr; 160 | Destroy(); 161 | if (quit_on_close_) { 162 | PostQuitMessage(0); 163 | } 164 | return 0; 165 | 166 | case WM_DPICHANGED: { 167 | auto newRectSize = reinterpret_cast(lparam); 168 | LONG newWidth = newRectSize->right - newRectSize->left; 169 | LONG newHeight = newRectSize->bottom - newRectSize->top; 170 | 171 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, 172 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE); 173 | 174 | return 0; 175 | } 176 | case WM_SIZE: { 177 | RECT rect = GetClientArea(); 178 | if (child_content_ != nullptr) { 179 | // Size and position the child window. 180 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, 181 | rect.bottom - rect.top, TRUE); 182 | } 183 | return 0; 184 | } 185 | 186 | case WM_ACTIVATE: 187 | if (child_content_ != nullptr) { 188 | SetFocus(child_content_); 189 | } 190 | return 0; 191 | } 192 | 193 | return DefWindowProc(window_handle_, message, wparam, lparam); 194 | } 195 | 196 | void Win32Window::Destroy() { 197 | OnDestroy(); 198 | 199 | if (window_handle_) { 200 | DestroyWindow(window_handle_); 201 | window_handle_ = nullptr; 202 | } 203 | if (g_active_window_count == 0) { 204 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); 205 | } 206 | } 207 | 208 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { 209 | return reinterpret_cast( 210 | GetWindowLongPtr(window, GWLP_USERDATA)); 211 | } 212 | 213 | void Win32Window::SetChildContent(HWND content) { 214 | child_content_ = content; 215 | SetParent(content, window_handle_); 216 | RECT frame = GetClientArea(); 217 | 218 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left, 219 | frame.bottom - frame.top, true); 220 | 221 | SetFocus(child_content_); 222 | } 223 | 224 | RECT Win32Window::GetClientArea() { 225 | RECT frame; 226 | GetClientRect(window_handle_, &frame); 227 | return frame; 228 | } 229 | 230 | HWND Win32Window::GetHandle() { 231 | return window_handle_; 232 | } 233 | 234 | void Win32Window::SetQuitOnClose(bool quit_on_close) { 235 | quit_on_close_ = quit_on_close; 236 | } 237 | 238 | bool Win32Window::OnCreate() { 239 | // No-op; provided for subclasses. 240 | return true; 241 | } 242 | 243 | void Win32Window::OnDestroy() { 244 | // No-op; provided for subclasses. 245 | } 246 | -------------------------------------------------------------------------------- /packages/flutter_background_service_android/android/src/main/java/id/flutter/flutter_background_service/FlutterBackgroundServicePlugin.java: -------------------------------------------------------------------------------- 1 | package id.flutter.flutter_background_service; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.ComponentName; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.ServiceConnection; 8 | import android.os.Handler; 9 | import android.os.IBinder; 10 | import android.util.Log; 11 | 12 | import androidx.annotation.NonNull; 13 | import androidx.core.content.ContextCompat; 14 | 15 | import org.json.JSONObject; 16 | import org.json.JSONArray; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | import io.flutter.embedding.engine.FlutterEngine; 22 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 23 | import io.flutter.embedding.engine.plugins.service.ServiceAware; 24 | import io.flutter.embedding.engine.plugins.service.ServicePluginBinding; 25 | import io.flutter.plugin.common.EventChannel; 26 | import io.flutter.plugin.common.JSONMethodCodec; 27 | import io.flutter.plugin.common.MethodCall; 28 | import io.flutter.plugin.common.MethodChannel; 29 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 30 | import io.flutter.plugin.common.MethodChannel.Result; 31 | import io.flutter.plugin.common.PluginRegistry.Registrar; 32 | 33 | /** 34 | * FlutterBackgroundServicePlugin 35 | */ 36 | public class FlutterBackgroundServicePlugin implements FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler { 37 | private static final String TAG = "BackgroundServicePlugin"; 38 | private Handler mainHandler; 39 | private Config config; 40 | private MethodChannel channel; 41 | private EventChannel eventChannel; 42 | private final Map eventSinks = new HashMap<>(); 43 | 44 | private Context context; 45 | 46 | public static final Pipe servicePipe = new Pipe(); 47 | public static final Pipe mainPipe = new Pipe(); 48 | 49 | public static void registerWith(FlutterEngine engine){ 50 | Log.d(TAG, "registering with FlutterEngine"); 51 | } 52 | 53 | private final Pipe.PipeListener listener = new Pipe.PipeListener() { 54 | @Override 55 | public void onReceived(JSONObject object) { 56 | receiveData(object); 57 | } 58 | }; 59 | 60 | 61 | @Override 62 | public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { 63 | this.context = flutterPluginBinding.getApplicationContext(); 64 | this.config = new Config(this.context); 65 | 66 | mainHandler = new Handler(context.getMainLooper()); 67 | 68 | channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "id.flutter/background_service/android/method", JSONMethodCodec.INSTANCE); 69 | channel.setMethodCallHandler(this); 70 | 71 | eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "id.flutter/background_service/android/event", JSONMethodCodec.INSTANCE); 72 | eventChannel.setStreamHandler(this); 73 | 74 | mainPipe.addListener(listener); 75 | } 76 | 77 | private void start() { 78 | WatchdogReceiver.enqueue(context); 79 | boolean isForeground = config.isForeground(); 80 | Intent intent = new Intent(context, BackgroundService.class); 81 | 82 | if (isForeground) { 83 | ContextCompat.startForegroundService(context, intent); 84 | } else { 85 | context.startService(intent); 86 | } 87 | } 88 | 89 | @Override 90 | public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { 91 | String method = call.method; 92 | JSONObject arg = (JSONObject) call.arguments; 93 | 94 | try { 95 | if ("configure".equals(method)) { 96 | long backgroundHandle = arg.getLong("background_handle"); 97 | boolean isForeground = arg.getBoolean("is_foreground_mode"); 98 | boolean autoStartOnBoot = arg.getBoolean("auto_start_on_boot"); 99 | boolean autoStart = arg.getBoolean("auto_start"); 100 | String initialNotificationTitle = arg.isNull("initial_notification_title") ? null : arg.getString("initial_notification_title"); 101 | String initialNotificationContent = arg.isNull("initial_notification_content") ? null : arg.getString("initial_notification_content"); 102 | String notificationChannelId = arg.isNull("notification_channel_id") ? null : arg.getString("notification_channel_id"); 103 | int foregroundNotificationId = arg.isNull("foreground_notification_id") ? null : arg.getInt("foreground_notification_id"); 104 | JSONArray foregroundServiceTypes = arg.isNull("foreground_service_types") ? null : arg.getJSONArray("foreground_service_types"); 105 | String foregroundServiceTypesStr = null; 106 | if (foregroundServiceTypes != null) { 107 | StringBuilder resultForegroundServiceType = new StringBuilder(); 108 | for (int i = 0; i < foregroundServiceTypes.length(); i++) { 109 | resultForegroundServiceType.append(foregroundServiceTypes.getString(i)); 110 | if (i < foregroundServiceTypes.length() - 1) { 111 | resultForegroundServiceType.append(","); 112 | } 113 | } 114 | foregroundServiceTypesStr = resultForegroundServiceType.toString(); 115 | } 116 | 117 | config.setBackgroundHandle(backgroundHandle); 118 | config.setIsForeground(isForeground); 119 | config.setAutoStartOnBoot(autoStartOnBoot); 120 | config.setInitialNotificationTitle(initialNotificationTitle); 121 | config.setInitialNotificationContent(initialNotificationContent); 122 | config.setNotificationChannelId(notificationChannelId); 123 | config.setForegroundNotificationId(foregroundNotificationId); 124 | config.setForegroundServiceTypes(foregroundServiceTypesStr); 125 | 126 | if (autoStart) { 127 | start(); 128 | } 129 | 130 | result.success(true); 131 | return; 132 | } 133 | 134 | if ("start".equals(method)) { 135 | start(); 136 | result.success(true); 137 | return; 138 | } 139 | 140 | if (method.equalsIgnoreCase("sendData")) { 141 | synchronized (servicePipe){ 142 | if (servicePipe.hasListener()){ 143 | servicePipe.invoke((JSONObject) call.arguments); 144 | result.success(true); 145 | return; 146 | } 147 | 148 | result.success(false); 149 | } 150 | return; 151 | } 152 | 153 | if (method.equalsIgnoreCase("isServiceRunning")) { 154 | result.success(isServiceRunning()); 155 | return; 156 | } 157 | 158 | result.notImplemented(); 159 | } catch (Exception e) { 160 | result.error("100", "Failed while read arguments", e.getMessage()); 161 | } 162 | } 163 | 164 | private boolean isServiceRunning() { 165 | ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 166 | for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 167 | if (BackgroundService.class.getName().equals(service.service.getClassName())) { 168 | return true; 169 | } 170 | } 171 | return false; 172 | } 173 | 174 | @Override 175 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { 176 | mainPipe.removeListener(listener); 177 | 178 | channel.setMethodCallHandler(null); 179 | channel = null; 180 | 181 | synchronized (eventSinks){ 182 | eventSinks.clear(); 183 | } 184 | eventChannel.setStreamHandler(null); 185 | eventChannel = null; 186 | } 187 | 188 | private void receiveData(JSONObject data) { 189 | final JSONObject arg = data; 190 | synchronized (this){ 191 | for (EventChannel.EventSink sink : 192 | eventSinks.values()) { 193 | mainHandler.post(new Runnable() { 194 | @Override 195 | public void run() { 196 | sink.success(arg); 197 | } 198 | }); 199 | } 200 | } 201 | } 202 | 203 | @Override 204 | public void onListen(Object arguments, EventChannel.EventSink events) { 205 | synchronized (this){ 206 | eventSinks.put(arguments, events); 207 | } 208 | } 209 | 210 | @Override 211 | public void onCancel(Object arguments) { 212 | synchronized (this){ 213 | eventSinks.remove(arguments); 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /packages/flutter_background_service/example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | import 'dart:ui'; 4 | 5 | import 'package:device_info_plus/device_info_plus.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_background_service/flutter_background_service.dart'; 8 | import 'package:flutter_local_notifications/flutter_local_notifications.dart'; 9 | import 'package:shared_preferences/shared_preferences.dart'; 10 | 11 | Future main() async { 12 | WidgetsFlutterBinding.ensureInitialized(); 13 | await initializeService(); 14 | runApp(const MyApp()); 15 | } 16 | 17 | Future initializeService() async { 18 | final service = FlutterBackgroundService(); 19 | 20 | /// OPTIONAL, using custom notification channel id 21 | const AndroidNotificationChannel channel = AndroidNotificationChannel( 22 | 'my_foreground', // id 23 | 'MY FOREGROUND SERVICE', // title 24 | description: 25 | 'This channel is used for important notifications.', // description 26 | importance: Importance.low, // importance must be at low or higher level 27 | ); 28 | 29 | final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = 30 | FlutterLocalNotificationsPlugin(); 31 | 32 | if (Platform.isIOS || Platform.isAndroid) { 33 | await flutterLocalNotificationsPlugin.initialize( 34 | const InitializationSettings( 35 | iOS: DarwinInitializationSettings(), 36 | android: AndroidInitializationSettings('ic_bg_service_small'), 37 | ), 38 | ); 39 | } 40 | 41 | await flutterLocalNotificationsPlugin 42 | .resolvePlatformSpecificImplementation< 43 | AndroidFlutterLocalNotificationsPlugin>() 44 | ?.createNotificationChannel(channel); 45 | 46 | await service.configure( 47 | androidConfiguration: AndroidConfiguration( 48 | // this will be executed when app is in foreground or background in separated isolate 49 | onStart: onStart, 50 | 51 | // auto start service 52 | autoStart: true, 53 | isForegroundMode: true, 54 | 55 | notificationChannelId: 'my_foreground', 56 | initialNotificationTitle: 'AWESOME SERVICE', 57 | initialNotificationContent: 'Initializing', 58 | foregroundServiceNotificationId: 888, 59 | foregroundServiceTypes: [AndroidForegroundType.location], 60 | ), 61 | iosConfiguration: IosConfiguration( 62 | // auto start service 63 | autoStart: true, 64 | 65 | // this will be executed when app is in foreground in separated isolate 66 | onForeground: onStart, 67 | 68 | // you have to enable background fetch capability on xcode project 69 | onBackground: onIosBackground, 70 | ), 71 | ); 72 | } 73 | 74 | // to ensure this is executed 75 | // run app from xcode, then from xcode menu, select Simulate Background Fetch 76 | 77 | @pragma('vm:entry-point') 78 | Future onIosBackground(ServiceInstance service) async { 79 | WidgetsFlutterBinding.ensureInitialized(); 80 | DartPluginRegistrant.ensureInitialized(); 81 | 82 | SharedPreferences preferences = await SharedPreferences.getInstance(); 83 | await preferences.reload(); 84 | final log = preferences.getStringList('log') ?? []; 85 | log.add(DateTime.now().toIso8601String()); 86 | await preferences.setStringList('log', log); 87 | 88 | return true; 89 | } 90 | 91 | @pragma('vm:entry-point') 92 | void onStart(ServiceInstance service) async { 93 | // Only available for flutter 3.0.0 and later 94 | DartPluginRegistrant.ensureInitialized(); 95 | 96 | // For flutter prior to version 3.0.0 97 | // We have to register the plugin manually 98 | 99 | SharedPreferences preferences = await SharedPreferences.getInstance(); 100 | await preferences.setString("hello", "world"); 101 | 102 | /// OPTIONAL when use custom notification 103 | final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = 104 | FlutterLocalNotificationsPlugin(); 105 | 106 | if (service is AndroidServiceInstance) { 107 | service.on('setAsForeground').listen((event) { 108 | service.setAsForegroundService(); 109 | }); 110 | 111 | service.on('setAsBackground').listen((event) { 112 | service.setAsBackgroundService(); 113 | }); 114 | } 115 | 116 | service.on('stopService').listen((event) { 117 | service.stopSelf(); 118 | }); 119 | 120 | // bring to foreground 121 | Timer.periodic(const Duration(seconds: 1), (timer) async { 122 | if (service is AndroidServiceInstance) { 123 | if (await service.isForegroundService()) { 124 | /// OPTIONAL for use custom notification 125 | /// the notification id must be equals with AndroidConfiguration when you call configure() method. 126 | flutterLocalNotificationsPlugin.show( 127 | 888, 128 | 'COOL SERVICE', 129 | 'Awesome ${DateTime.now()}', 130 | const NotificationDetails( 131 | android: AndroidNotificationDetails( 132 | 'my_foreground', 133 | 'MY FOREGROUND SERVICE', 134 | icon: 'ic_bg_service_small', 135 | ongoing: true, 136 | ), 137 | ), 138 | ); 139 | 140 | // if you don't using custom notification, uncomment this 141 | service.setForegroundNotificationInfo( 142 | title: "My App Service", 143 | content: "Updated at ${DateTime.now()}", 144 | ); 145 | } 146 | } 147 | 148 | /// you can see this log in logcat 149 | debugPrint('FLUTTER BACKGROUND SERVICE: ${DateTime.now()}'); 150 | 151 | // test using external plugin 152 | final deviceInfo = DeviceInfoPlugin(); 153 | String? device; 154 | if (Platform.isAndroid) { 155 | final androidInfo = await deviceInfo.androidInfo; 156 | device = androidInfo.model; 157 | } else if (Platform.isIOS) { 158 | final iosInfo = await deviceInfo.iosInfo; 159 | device = iosInfo.model; 160 | } 161 | 162 | service.invoke( 163 | 'update', 164 | { 165 | "current_date": DateTime.now().toIso8601String(), 166 | "device": device, 167 | }, 168 | ); 169 | }); 170 | } 171 | 172 | class MyApp extends StatefulWidget { 173 | const MyApp({Key? key}) : super(key: key); 174 | 175 | @override 176 | State createState() => _MyAppState(); 177 | } 178 | 179 | class _MyAppState extends State { 180 | String text = "Stop Service"; 181 | @override 182 | Widget build(BuildContext context) { 183 | return MaterialApp( 184 | home: Scaffold( 185 | appBar: AppBar( 186 | title: const Text('Service App'), 187 | ), 188 | body: Column( 189 | children: [ 190 | StreamBuilder?>( 191 | stream: FlutterBackgroundService().on('update'), 192 | builder: (context, snapshot) { 193 | if (!snapshot.hasData) { 194 | return const Center( 195 | child: CircularProgressIndicator(), 196 | ); 197 | } 198 | 199 | final data = snapshot.data!; 200 | String? device = data["device"]; 201 | DateTime? date = DateTime.tryParse(data["current_date"]); 202 | return Column( 203 | children: [ 204 | Text(device ?? 'Unknown'), 205 | Text(date.toString()), 206 | ], 207 | ); 208 | }, 209 | ), 210 | ElevatedButton( 211 | child: const Text("Foreground Mode"), 212 | onPressed: () => 213 | FlutterBackgroundService().invoke("setAsForeground"), 214 | ), 215 | ElevatedButton( 216 | child: const Text("Background Mode"), 217 | onPressed: () => 218 | FlutterBackgroundService().invoke("setAsBackground"), 219 | ), 220 | ElevatedButton( 221 | child: Text(text), 222 | onPressed: () async { 223 | final service = FlutterBackgroundService(); 224 | var isRunning = await service.isRunning(); 225 | isRunning 226 | ? service.invoke("stopService") 227 | : service.startService(); 228 | 229 | setState(() { 230 | text = isRunning ? 'Start Service' : 'Stop Service'; 231 | }); 232 | }, 233 | ), 234 | const Expanded( 235 | child: LogView(), 236 | ), 237 | ], 238 | ), 239 | ), 240 | ); 241 | } 242 | } 243 | 244 | class LogView extends StatefulWidget { 245 | const LogView({Key? key}) : super(key: key); 246 | 247 | @override 248 | State createState() => _LogViewState(); 249 | } 250 | 251 | class _LogViewState extends State { 252 | late final Timer timer; 253 | List logs = []; 254 | 255 | @override 256 | void initState() { 257 | super.initState(); 258 | timer = Timer.periodic(const Duration(seconds: 1), (timer) async { 259 | final SharedPreferences sp = await SharedPreferences.getInstance(); 260 | await sp.reload(); 261 | logs = sp.getStringList('log') ?? []; 262 | if (mounted) { 263 | setState(() {}); 264 | } 265 | }); 266 | } 267 | 268 | @override 269 | void dispose() { 270 | timer.cancel(); 271 | super.dispose(); 272 | } 273 | 274 | @override 275 | Widget build(BuildContext context) { 276 | return ListView.builder( 277 | itemCount: logs.length, 278 | itemBuilder: (context, index) { 279 | final log = logs.elementAt(index); 280 | return Text(log); 281 | }, 282 | ); 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | ansi_styles: 5 | dependency: transitive 6 | description: 7 | name: ansi_styles 8 | sha256: "9c656cc12b3c27b17dd982b2cc5c0cfdfbdabd7bc8f3ae5e8542d9867b47ce8a" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "0.3.2+1" 12 | args: 13 | dependency: transitive 14 | description: 15 | name: args 16 | sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.4.2" 20 | async: 21 | dependency: transitive 22 | description: 23 | name: async 24 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.11.0" 28 | boolean_selector: 29 | dependency: transitive 30 | description: 31 | name: boolean_selector 32 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.1.1" 36 | charcode: 37 | dependency: transitive 38 | description: 39 | name: charcode 40 | sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.3.1" 44 | cli_launcher: 45 | dependency: transitive 46 | description: 47 | name: cli_launcher 48 | sha256: "5e7e0282b79e8642edd6510ee468ae2976d847a0a29b3916e85f5fa1bfe24005" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "0.3.1" 52 | cli_util: 53 | dependency: transitive 54 | description: 55 | name: cli_util 56 | sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "0.4.1" 60 | clock: 61 | dependency: transitive 62 | description: 63 | name: clock 64 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "1.1.1" 68 | collection: 69 | dependency: transitive 70 | description: 71 | name: collection 72 | sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.19.0" 76 | conventional_commit: 77 | dependency: transitive 78 | description: 79 | name: conventional_commit 80 | sha256: dec15ad1118f029c618651a4359eb9135d8b88f761aa24e4016d061cd45948f2 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "0.6.0+1" 84 | file: 85 | dependency: transitive 86 | description: 87 | name: file 88 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "7.0.0" 92 | glob: 93 | dependency: transitive 94 | description: 95 | name: glob 96 | sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "2.1.2" 100 | graphs: 101 | dependency: transitive 102 | description: 103 | name: graphs 104 | sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "2.3.1" 108 | http: 109 | dependency: transitive 110 | description: 111 | name: http 112 | sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "1.2.1" 116 | http_parser: 117 | dependency: transitive 118 | description: 119 | name: http_parser 120 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "4.0.2" 124 | intl: 125 | dependency: transitive 126 | description: 127 | name: intl 128 | sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "0.19.0" 132 | io: 133 | dependency: transitive 134 | description: 135 | name: io 136 | sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "1.0.4" 140 | json_annotation: 141 | dependency: transitive 142 | description: 143 | name: json_annotation 144 | sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "4.8.1" 148 | matcher: 149 | dependency: transitive 150 | description: 151 | name: matcher 152 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "0.12.16" 156 | melos: 157 | dependency: "direct main" 158 | description: 159 | name: melos 160 | sha256: a3f06ed871e0348cb99909ad5ddf5f8b53cc61d894c302b5417d2db1ee7ec381 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "6.1.0" 164 | meta: 165 | dependency: transitive 166 | description: 167 | name: meta 168 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "1.15.0" 172 | mustache_template: 173 | dependency: transitive 174 | description: 175 | name: mustache_template 176 | sha256: a46e26f91445bfb0b60519be280555b06792460b27b19e2b19ad5b9740df5d1c 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "2.0.0" 180 | path: 181 | dependency: transitive 182 | description: 183 | name: path 184 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "1.8.3" 188 | platform: 189 | dependency: transitive 190 | description: 191 | name: platform 192 | sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "3.1.5" 196 | pool: 197 | dependency: transitive 198 | description: 199 | name: pool 200 | sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "1.5.1" 204 | process: 205 | dependency: transitive 206 | description: 207 | name: process 208 | sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "5.0.2" 212 | prompts: 213 | dependency: transitive 214 | description: 215 | name: prompts 216 | sha256: "3773b845e85a849f01e793c4fc18a45d52d7783b4cb6c0569fad19f9d0a774a1" 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "2.0.0" 220 | pub_semver: 221 | dependency: transitive 222 | description: 223 | name: pub_semver 224 | sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "2.1.4" 228 | pub_updater: 229 | dependency: transitive 230 | description: 231 | name: pub_updater 232 | sha256: "54e8dc865349059ebe7f163d6acce7c89eb958b8047e6d6e80ce93b13d7c9e60" 233 | url: "https://pub.dev" 234 | source: hosted 235 | version: "0.4.0" 236 | pubspec: 237 | dependency: transitive 238 | description: 239 | name: pubspec 240 | sha256: f534a50a2b4d48dc3bc0ec147c8bd7c304280fff23b153f3f11803c4d49d927e 241 | url: "https://pub.dev" 242 | source: hosted 243 | version: "2.3.0" 244 | quiver: 245 | dependency: transitive 246 | description: 247 | name: quiver 248 | sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 249 | url: "https://pub.dev" 250 | source: hosted 251 | version: "3.2.1" 252 | source_span: 253 | dependency: transitive 254 | description: 255 | name: source_span 256 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 257 | url: "https://pub.dev" 258 | source: hosted 259 | version: "1.10.0" 260 | stack_trace: 261 | dependency: transitive 262 | description: 263 | name: stack_trace 264 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 265 | url: "https://pub.dev" 266 | source: hosted 267 | version: "1.11.0" 268 | stream_channel: 269 | dependency: transitive 270 | description: 271 | name: stream_channel 272 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 273 | url: "https://pub.dev" 274 | source: hosted 275 | version: "2.1.1" 276 | string_scanner: 277 | dependency: transitive 278 | description: 279 | name: string_scanner 280 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 281 | url: "https://pub.dev" 282 | source: hosted 283 | version: "1.2.0" 284 | term_glyph: 285 | dependency: transitive 286 | description: 287 | name: term_glyph 288 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 289 | url: "https://pub.dev" 290 | source: hosted 291 | version: "1.2.1" 292 | test_api: 293 | dependency: transitive 294 | description: 295 | name: test_api 296 | sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" 297 | url: "https://pub.dev" 298 | source: hosted 299 | version: "0.6.0" 300 | typed_data: 301 | dependency: transitive 302 | description: 303 | name: typed_data 304 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 305 | url: "https://pub.dev" 306 | source: hosted 307 | version: "1.3.2" 308 | uri: 309 | dependency: transitive 310 | description: 311 | name: uri 312 | sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" 313 | url: "https://pub.dev" 314 | source: hosted 315 | version: "1.0.0" 316 | web: 317 | dependency: transitive 318 | description: 319 | name: web 320 | sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" 321 | url: "https://pub.dev" 322 | source: hosted 323 | version: "0.5.1" 324 | yaml: 325 | dependency: transitive 326 | description: 327 | name: yaml 328 | sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" 329 | url: "https://pub.dev" 330 | source: hosted 331 | version: "3.1.2" 332 | yaml_edit: 333 | dependency: transitive 334 | description: 335 | name: yaml_edit 336 | sha256: "1579d4a0340a83cf9e4d580ea51a16329c916973bffd5bd4b45e911b25d46bfd" 337 | url: "https://pub.dev" 338 | source: hosted 339 | version: "2.1.1" 340 | sdks: 341 | dart: ">=3.4.0 <4.0.0" 342 | flutter: ">=3.0.0" 343 | --------------------------------------------------------------------------------