Skip to content

Commit

Permalink
docs: Update example and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Dev-hwang committed Sep 9, 2024
1 parent a6ce84b commit 2658020
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 43 deletions.
34 changes: 14 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ After adding the `flutter_foreground_task` plugin to the flutter project, we nee

### :baby_chick: Android

Open the `AndroidManifest.xml` file and specify the service inside the `<application>` tag as follows. If you want the foreground service to run only when the app is running, add `android:stopWithTask` option.
Open the `AndroidManifest.xml` file and specify the service inside the `<application>` tag as follows.

If you want the foreground service to run only when the app is running, add `android:stopWithTask="true"` option.

As it is mentioned in the Android Guidelines, in Android 14, to start a FG service, you need to specify `android:foregroundServiceType`.

Expand All @@ -47,7 +49,6 @@ Change the type with your type (all types are listed in the link above).
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" />

<!-- Warning: Do not change service name. -->
<!-- Add android:stopWithTask option only when necessary. -->
<service
android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
android:foregroundServiceType="dataSync|remoteMessaging"
Expand Down Expand Up @@ -267,9 +268,9 @@ Future<void> _requestPermissions() async {
// Android 13+, you need to allow notification permission to display foreground service notification.
//
// iOS: If you need notification, ask for permission.
final NotificationPermission notificationPermissionStatus =
final NotificationPermission notificationPermission =
await FlutterForegroundTask.checkNotificationPermission();
if (notificationPermissionStatus != NotificationPermission.granted) {
if (notificationPermission != NotificationPermission.granted) {
await FlutterForegroundTask.requestNotificationPermission();
}
Expand Down Expand Up @@ -308,7 +309,7 @@ Future<void> _requestPermissions() async {
}
}
Future<void> _initService() async {
void _initService() {
FlutterForegroundTask.init(
androidNotificationOptions: AndroidNotificationOptions(
channelId: 'foreground_service',
Expand All @@ -319,7 +320,7 @@ Future<void> _initService() async {
priority: NotificationPriority.LOW,
),
iosNotificationOptions: const IOSNotificationOptions(
showNotification: true,
showNotification: false,
playSound: false,
),
foregroundTaskOptions: ForegroundTaskOptions(
Expand Down Expand Up @@ -398,6 +399,8 @@ class FirstTaskHandler extends TaskHandler {
@override
void onRepeatEvent(DateTime timestamp) {
_count++;
if (_count == 10) {
FlutterForegroundTask.updateService(
foregroundTaskOptions: ForegroundTaskOptions(
Expand All @@ -417,8 +420,6 @@ class FirstTaskHandler extends TaskHandler {
};
FlutterForegroundTask.sendDataToMain(data);
}
_count++;
}
@override
Expand Down Expand Up @@ -481,33 +482,26 @@ JSON and serialization >> https://docs.flutter.dev/data-and-backend/serializatio
// TaskHandler
@override
void onStart(DateTime timestamp) {
// TaskHandler -> UI
// TaskHandler -> Main(UI)
FlutterForegroundTask.sendDataToMain(Object);
}
// Main(UI)::onReceiveTaskData
// Main(UI)
void _onReceiveTaskData(Object data) {
if (data is Map<String, dynamic>) {
final dynamic timestampMillis = data["timestampMillis"];
if (timestampMillis != null) {
final DateTime timestamp =
DateTime.fromMillisecondsSinceEpoch(timestampMillis, isUtc: true);
print('timestamp: ${timestamp.toString()}');
}
}
print('onReceiveTaskData: $data');
}
```

```dart
// Main(UI)
void _sendDataToTask() {
// UI -> TaskHandler
// Main(UI) -> TaskHandler
//
// The Map collection can only be sent in json format, such as Map<String, dynamic>.
FlutterForegroundTask.sendDataToTask(Object);
}
// TaskHandler::onReceiveData
// TaskHandler
@override
void onReceiveData(Object data) {
print('onReceiveData: $data');
Expand Down
86 changes: 63 additions & 23 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
Expand All @@ -19,12 +18,28 @@ void startCallback() {
}

class MyTaskHandler extends TaskHandler {
static const String incrementCountCommand = 'incrementCount';

int _count = 0;

void _incrementCount() {
_count++;

// Update notification content.
FlutterForegroundTask.updateService(
notificationTitle: 'Hello MyTaskHandler :)',
notificationText: 'count: $_count',
);

// Send data to main isolate.
FlutterForegroundTask.sendDataToMain(_count);
}

// Called when the task is started.
@override
void onStart(DateTime timestamp) {
print('onStart');
_incrementCount();
}

// Called by eventAction in [ForegroundTaskOptions].
Expand All @@ -33,12 +48,7 @@ class MyTaskHandler extends TaskHandler {
// - repeat(interval) : Call onRepeatEvent at milliseconds interval.
@override
void onRepeatEvent(DateTime timestamp) {
FlutterForegroundTask.updateService(notificationText: 'count: $_count');

// Send data to main isolate.
FlutterForegroundTask.sendDataToMain(_count);

_count++;
_incrementCount();
}

// Called when the task is destroyed.
Expand All @@ -51,6 +61,9 @@ class MyTaskHandler extends TaskHandler {
@override
void onReceiveData(Object data) {
print('onReceiveData: $data');
if (data == incrementCountCommand) {
_incrementCount();
}
}

// Called when the notification button is pressed.
Expand Down Expand Up @@ -80,7 +93,7 @@ class MyTaskHandler extends TaskHandler {
}

class ExampleApp extends StatelessWidget {
const ExampleApp({Key? key}) : super(key: key);
const ExampleApp({super.key});

@override
Widget build(BuildContext context) {
Expand All @@ -94,20 +107,22 @@ class ExampleApp extends StatelessWidget {
}

class ExamplePage extends StatefulWidget {
const ExamplePage({Key? key}) : super(key: key);
const ExamplePage({super.key});

@override
State<StatefulWidget> createState() => _ExamplePageState();
}

class _ExamplePageState extends State<ExamplePage> {
final ValueNotifier<Object?> _receivedTaskData = ValueNotifier(null);

Future<void> _requestPermissions() async {
// Android 13+, you need to allow notification permission to display foreground service notification.
//
// iOS: If you need notification, ask for permission.
final NotificationPermission notificationPermissionStatus =
final NotificationPermission notificationPermission =
await FlutterForegroundTask.checkNotificationPermission();
if (notificationPermissionStatus != NotificationPermission.granted) {
if (notificationPermission != NotificationPermission.granted) {
await FlutterForegroundTask.requestNotificationPermission();
}

Expand Down Expand Up @@ -146,7 +161,7 @@ class _ExamplePageState extends State<ExamplePage> {
}
}

Future<void> _initService() async {
void _initService() {
FlutterForegroundTask.init(
androidNotificationOptions: AndroidNotificationOptions(
channelId: 'foreground_service',
Expand All @@ -157,7 +172,7 @@ class _ExamplePageState extends State<ExamplePage> {
priority: NotificationPriority.LOW,
),
iosNotificationOptions: const IOSNotificationOptions(
showNotification: true,
showNotification: false,
playSound: false,
),
foregroundTaskOptions: ForegroundTaskOptions(
Expand Down Expand Up @@ -192,15 +207,12 @@ class _ExamplePageState extends State<ExamplePage> {
}

void _onReceiveTaskData(Object data) {
if (data is int) {
print('count: $data');
}
print('onReceiveTaskData: $data');
_receivedTaskData.value = data;
}

void _sendRandomData() {
final Random random = Random();
final int data = random.nextInt(100);
FlutterForegroundTask.sendDataToTask(data);
void _incrementCount() {
FlutterForegroundTask.sendDataToTask(MyTaskHandler.incrementCountCommand);
}

@override
Expand All @@ -220,6 +232,7 @@ class _ExamplePageState extends State<ExamplePage> {
void dispose() {
// Remove a callback to receive data sent from the TaskHandler.
FlutterForegroundTask.removeTaskDataCallback(_onReceiveTaskData);
_receivedTaskData.dispose();
super.dispose();
}

Expand All @@ -242,20 +255,47 @@ class _ExamplePageState extends State<ExamplePage> {
}

Widget _buildContentView() {
return Column(
children: [
Expanded(child: _buildCommunicationText()),
_buildServiceControlButtons(),
],
);
}

Widget _buildCommunicationText() {
return ValueListenableBuilder(
valueListenable: _receivedTaskData,
builder: (context, data, _) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You received data from TaskHandler:'),
Text('$data', style: Theme.of(context).textTheme.headlineMedium),
],
),
);
},
);
}

Widget _buildServiceControlButtons() {
buttonBuilder(String text, {VoidCallback? onPressed}) {
return ElevatedButton(
onPressed: onPressed,
child: Text(text),
);
}

return Center(
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
buttonBuilder('start service', onPressed: _startService),
buttonBuilder('stop service', onPressed: _stopService),
buttonBuilder('send random data', onPressed: _sendRandomData),
buttonBuilder('increment count', onPressed: _incrementCount),
],
),
);
Expand Down

0 comments on commit 2658020

Please sign in to comment.