Reputation: 5
I try to pass the parameter in this way, but it doesn't work
alarm() async {
int i = 1;
await AndroidAlarmManager.oneShot(
Duration(seconds: 3),
2,
() => callback(i),
wakeup: true,
).then((val) => print('set up:' + val.toString()));
}
and
alarm() async {
int i = 1;
await AndroidAlarmManager.oneShot(
Duration(seconds: 3),
2,
() {
callback(i);
},
wakeup: true,
).then((val) => print('set up:' + val.toString()));
}
in console log print like this :
I/flutter ( 9306): set up:false
callback function :
static Future<void> callback(int i) async {
print('Alarm fired!' + '$i');
uiSendPort ??= IsolateNameServer.lookupPortByName(isolateName);
uiSendPort?.send(null);
}
What Im doing wrong?
Upvotes: 0
Views: 838
Reputation: 54367
Reason
from source code
/// `id` will passed to `callback` if it is of type `Function(int)`
In your case, with correct use of callback
, and id
is 2
, it will always print Alarm fired!2
alarm() async {
int i = 1;
await AndroidAlarmManager.oneShot(
Duration(seconds: 3),
2,
callback,
wakeup: true,
).then((val) => print('set up:' + val.toString()));
}
Solution
/// The `callback` will run whether or not the main application is running or
/// in the foreground. It will run in the Isolate owned by the
/// AndroidAlarmManager service.
To allow callback
get parameter, you can follow official example use SharedPreferences
code snippet
static Future<void> callback(int i) async {
print('Alarm fired!' + '$i');
// Get the previous cached count and increment it.
final prefs = await SharedPreferences.getInstance();
int currentCount = prefs.getInt(countKey) ?? 0;
await prefs.setInt(countKey, currentCount + 1);
// This will be null if we're running in the background.
uiSendPort ??= IsolateNameServer.lookupPortByName(isolateName);
uiSendPort?.send(null);
}
full test code
import 'dart:isolate';
import 'dart:math';
import 'dart:ui';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
/// The [SharedPreferences] key to access the alarm fire count.
const String countKey = 'count';
/// The name associated with the UI isolate's [SendPort].
const String isolateName = 'isolate';
/// A port used to communicate from a background isolate to the UI isolate.
final ReceivePort port = ReceivePort();
/// Global [SharedPreferences] object.
SharedPreferences prefs;
Future<void> main() async {
// TODO(bkonyi): uncomment
WidgetsFlutterBinding.ensureInitialized();
// Register the UI isolate's SendPort to allow for communication from the
// background isolate.
IsolateNameServer.registerPortWithName(
port.sendPort,
isolateName,
);
prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey(countKey)) {
await prefs.setInt(countKey, 0);
}
runApp(AlarmManagerExampleApp());
}
/// Example app for Espresso plugin.
class AlarmManagerExampleApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: _AlarmHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class _AlarmHomePage extends StatefulWidget {
_AlarmHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_AlarmHomePageState createState() => _AlarmHomePageState();
}
class _AlarmHomePageState extends State<_AlarmHomePage> {
int _counter = 0;
@override
void initState() {
super.initState();
AndroidAlarmManager.initialize();
// Register for events from the background isolate. These messages will
// always coincide with an alarm firing.
port.listen((_) async => await _incrementCounter());
}
alarm() async {
int i = 1;
await AndroidAlarmManager.oneShot(
Duration(seconds: 3),
2,
callback,
wakeup: true,
).then((val) => print('set up:' + val.toString()));
}
Future<void> _incrementCounter() async {
print('Increment counter!');
// Ensure we've loaded the updated count from the background isolate.
await prefs.reload();
setState(() {
_counter++;
});
}
// The background
static SendPort uiSendPort;
// The callback for our alarm
static Future<void> callback(int i) async {
print('Alarm fired!' + '$i');
// Get the previous cached count and increment it.
final prefs = await SharedPreferences.getInstance();
int currentCount = prefs.getInt(countKey) ?? 0;
await prefs.setInt(countKey, currentCount + 1);
// This will be null if we're running in the background.
uiSendPort ??= IsolateNameServer.lookupPortByName(isolateName);
uiSendPort?.send(null);
}
@override
Widget build(BuildContext context) {
final textStyle = Theme.of(context).textTheme.headline4;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
alarm();
},
child: Text('alarm')),
Text(
'Alarm fired $_counter times',
style: textStyle,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Total alarms fired: ',
style: textStyle,
),
Text(
prefs.getInt(countKey).toString(),
key: ValueKey('BackgroundCountText'),
style: textStyle,
),
],
),
ElevatedButton(
child: Text(
'Schedule OneShot Alarm',
),
key: ValueKey('RegisterOneShotAlarm'),
onPressed: () async {
await AndroidAlarmManager.oneShot(
const Duration(seconds: 5),
// Ensure we have a unique alarm ID.
Random().nextInt(pow(2, 31).toInt()),
callback,
exact: true,
wakeup: true,
);
},
),
],
),
),
);
}
}
Upvotes: 3