{"id":605,"date":"2021-04-29T18:32:45","date_gmt":"2021-04-29T09:32:45","guid":{"rendered":"http:\/\/localhost:8000\/?p=605"},"modified":"2021-05-16T18:43:17","modified_gmt":"2021-05-16T09:43:17","slug":"flutter-background-timer-app","status":"publish","type":"post","link":"http:\/\/localhost:8000\/2021\/04\/flutter-background-timer-app.html","title":{"rendered":"Flutter \u3067\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u3082\u52d5\u304f\u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\u3092\u4f5c\u3063\u305f"},"content":{"rendered":"
<\/p>\n
\u5c11\u3057\u524d\u306b\u4f1a\u793e\u306e\u30d6\u30ed\u30b0\u3067\u4ee5\u4e0b\u306e\u8a18\u4e8b\u3092\u66f8\u304d\u307e\u3057\u305f\u3002 \u3053\u306e\u30a2\u30d7\u30ea\u306b\u306f\u3001\u300c\u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3059\u308b\u3068\u30bf\u30a4\u30de\u30fc\u304c\u505c\u6b62\u3057\u3066\u3057\u307e\u3046\u300d\u3068\u3044\u3046\u81f4\u547d\u7684\u306a\u554f\u984c\u304c\u3042\u308a\u307e\u3057\u305f\u304c\u3001\u305d\u306e\u5bfe\u51e6\u65b9\u6cd5\u304c\u5206\u304b\u3063\u305f\u306e\u3067\u3001\u7d39\u4ecb\u3057\u305f\u3044\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n \u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3059\u308b\u3068\u3001\u30a2\u30d7\u30ea\u304c\u4e00\u6642\u505c\u6b62\u3057\u3066\u3057\u307e\u3044\u3001\u30bf\u30a4\u30de\u30fc\u304c\u6b62\u307e\u3063\u3066\u3057\u307e\u3046\u3002<\/p>\n \u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u30bf\u30a4\u30df\u30f3\u30b0\u3068\u3001\u30d5\u30a9\u30a2\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u5fa9\u5e30\u3057\u305f\u30bf\u30a4\u30df\u30f3\u30b0\u3067\u4ee5\u4e0b\u306e\u51e6\u7406\u3092\u884c\u3046\u4f5c\u6226\u3067\u3044\u3053\u3046\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n \u6ce8\uff09 Flutter \u3067\u306f\u30a2\u30d7\u30ea\u3092\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u8d77\u52d5\u3055\u305b\u3063\u3071\u306a\u3057\u306b\u3059\u308b\u65b9\u6cd5\u306f\u306a\u3055\u305d\u3046\u306a\u306e\u3067\u3001\u4e0a\u8a18\u3092\u63a1\u7528\u3057\u307e\u3057\u305f\u3002<\/p>\n Flutter \u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30a4\u30d9\u30f3\u30c8\u3092\u30ea\u30c3\u30b9\u30f3\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u306f\u3001iOS \u306f\u3053\u3061\u3089<\/a> \u3001Android\u306f \u3053\u3061\u3089<\/a> \u306b\u8a18\u8f09\u3055\u308c\u3066\u304a\u308a\u3001\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30a4\u30d9\u30f3\u30c8\u306eEnum\u5024\u306e\u8aac\u660e\u3082 \u3053\u3061\u3089<\/a> \u306b\u3042\u308a\u307e\u3059\u3002<\/p>\n \u5b9f\u969b\u306b\u8a66\u3057\u3066\u307f\u308b\u3068\u3001\u4eca\u56de\u306f \u3061\u306a\u307f\u306b\u3001\u3053\u306e\u30a4\u30d9\u30f3\u30c8\u3092\u3059\u308b\u65b9\u6cd5\u306f\u3068\u3066\u3082\u7c21\u5358\u3067\u3059\u3002<\/p>\n State\u30af\u30e9\u30b9\u3067 \u8aac\u660e\u7528\u306b10\u79d2\u3092\u30ab\u30a6\u30f3\u30c8\u30c0\u30a6\u30f3\u3059\u308b\u3060\u3051\u306e\u30a2\u30d7\u30ea\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002<\/p>\n <\/p>\n \u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u3066\u3082\u3001<\/p>\n \u3068\u3044\u3046\u5bfe\u5fdc\u3092\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n \u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30a4\u30d9\u30f3\u30c8\u306e \u3053\u3061\u3089\u3001\u4e00\u898b\u5b8c\u74a7\u306b\u898b\u3048\u308b\u306e\u3067\u3059\u304c\u3001\u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\u306a\u306e\u3067\u3001\u672c\u5f53\u306f\u30ed\u30fc\u30ab\u30eb\u901a\u77e5\u3067\u306f\u306a\u304f\u30a2\u30e9\u30fc\u30e0\uff08\u9cf4\u308a\u7d9a\u3051\u308b\uff09\u3068\u3057\u3066\u5b9f\u884c\u3057\u305f\u304b\u3063\u305f\u3067\u3059\u3002<\/p>\n \u3057\u304b\u3057\u3001\u30a2\u30e9\u30fc\u30e0\u3092\u9cf4\u3089\u3059\u305f\u3081\u306e Flutter Ringtone Player<\/a> \u306f\u3001\u305d\u306e\u77ac\u9593\u306b\u7740\u4fe1\u97f3\u3092\u9cf4\u3089\u3059\u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u767b\u9332\u306f\u3067\u304d\u305a\u3001\u4ed6\u306b\u30a2\u30e9\u30fc\u30e0\u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u767b\u9332\u3067\u304d\u308b\u3088\u3046\u306a\u30d7\u30e9\u30b0\u30a4\u30f3\u3082\u898b\u5f53\u305f\u3089\u306a\u3044\u306e\u3067\u4eca\u56de\u306f\u8ae6\u3081\u307e\u3057\u305f\u3002<\/p>\n \u4eca\u56de\u3001\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u3066\u3082\u3061\u3083\u3093\u3068\u6642\u9593\u3092\u9032\u3081\u3066\u3001\u6642\u9593\u304c\u6765\u305f\u3089\u901a\u77e5\u3057\u3066\u304f\u308c\u308b\u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002 \u3061\u306a\u307f\u306b\u3001\u5b50\u4f9b\u304cYoutube\u3084\u30a2\u30de\u30be\u30f3\u30d7\u30e9\u30a4\u30e0\u3092\u898b\u308b\u7aef\u672b\u304ciPad\u306a\u306e\u3067\u3059\u304c\u3001App Store\u306b\u767b\u9332\u3059\u308b\u306e\u306f\u6bce\u5e741\u4e07\u5186\u3050\u3089\u3044\u304b\u304b\u308b\u3089\u3057\u3044\u306e\u3067\u304a\u91d1\u3092\u6255\u3046\u6c17\u304c\u8d77\u304d\u305a\u3001Android Studio\u304b\u3089\u30ea\u30ea\u30fc\u30b9\u30e2\u30fc\u30c9\u3067\u76f4\u63a5\u5b9f\u6a5f\u306b\u30c7\u30d7\u30ed\u30a4\u3057\u3066\u4f7f\u3063\u3066\u3044\u307e\u3059\u30022,3\u65e5\u3067\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u308b\u306e\u3067\u3001\u3057\u3087\u3063\u3061\u3085\u3046\u30c7\u30d7\u30ed\u30a4\u304c\u5fc5\u8981\u306a\u306e\u304c\u9762\u5012\u3067\u3059\u304c\uff08\u6d99\uff09<\/p>\n","protected":false},"excerpt":{"rendered":" \u5c11\u3057\u524d\u306b\u4f1a\u793e\u306e\u30d6\u30ed\u30b0\u3067\u4ee5\u4e0b\u306e\u8a18\u4e8b\u3092\u66f8\u304d\u307e\u3057\u305f\u3002 Flutter\u3067\u304a\u52c9\u5f37\u6642\u9593\u7ba1\u7406\u7528\u306e\u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\u3092\u4f5c\u3063\u305f \u3053\u306e\u30a2\u30d7\u30ea\u306b\u306f\u3001\u300c\u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3059\u308b\u3068\u30bf\u30a4\u30de\u30fc\u304c\u505c\u6b62\u3057\u3066\u3057\u307e\u3046\u300d\u3068\u3044\u3046\u81f4\u547d\u7684\u306a\u554f\u984c\u304c\u3042\u308a\u307e\u3057\u305f\u304c\u3001\u305d\u306e\u5bfe\u51e6\u65b9\u6cd5\u304c\u5206\u304b\u3063\u305f\u306e\u3067\u3001\u7d39\u4ecb\u3057\u305f\u3044\u3068\u601d\u3044\u307e\u3059\u3002 \u554f\u984c\u70b9 \u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3059\u308b\u3068\u3001\u30a2\u30d7\u30ea\u304c\u4e00\u6642\u505c\u6b62\u3057\u3066\u3057\u307e\u3044\u3001\u30bf\u30a4\u30de\u30fc\u304c\u6b62\u307e\u3063\u3066\u3057\u307e\u3046\u3002 \u5bfe\u5fdc\u65b9\u91dd \u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u30bf\u30a4\u30df\u30f3\u30b0\u3068\u3001\u30d5\u30a9\u30a2\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u5fa9\u5e30\u3057\u305f\u30bf\u30a4\u30df\u30f3\u30b0\u3067\u4ee5\u4e0b\u306e\u51e6\u7406\u3092\u884c\u3046\u4f5c\u6226\u3067\u3044\u3053\u3046\u3068\u601d\u3044\u307e\u3059\u3002 \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30c9\u306b\u9077\u79fb\u3057\u305f\u30bf\u30a4\u30df\u30f3\u30b0 \u305d\u306e\u6642\u70b9\u306e\u6642\u9593\u3092\u5143\u306b\u3001\u30ed\u30fc\u30ab\u30eb\u901a\u77e5\u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u767b\u9332\u3059\u308b\uff08\u30ed\u30fc\u30ab\u30eb\u901a\u77e5\u306f\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u3082\u6642\u9593\u304c\u304f\u308c\u3070\u5b9f\u884c\u3055\u308c\u308b\uff09 \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u65e5\u6642\u3092\u8a18\u9332\u3059\u308b \u30d5\u30a9\u30a2\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u5fa9\u5e30\u3057\u305f\u30bf\u30a4\u30df\u30f3\u30b0 \u30ed\u30fc\u30ab\u30eb\u901a\u77e5\u30bf\u30a4\u30de\u30fc\u3092\u505c\u6b62\u3059\u308b \u30d5\u30a9\u30a2\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u5fa9\u5e30 <\/span>Continue Reading<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[38],"tags":[],"_links":{"self":[{"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/posts\/605"}],"collection":[{"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/comments?post=605"}],"version-history":[{"count":1,"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/posts\/605\/revisions"}],"predecessor-version":[{"id":607,"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/posts\/605\/revisions\/607"}],"wp:attachment":[{"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/media?parent=605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/categories?post=605"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/localhost:8000\/wp-json\/wp\/v2\/tags?post=605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}
\nFlutter\u3067\u304a\u52c9\u5f37\u6642\u9593\u7ba1\u7406\u7528\u306e\u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\u3092\u4f5c\u3063\u305f<\/a><\/p>\n\u554f\u984c\u70b9<\/h2>\n
\u5bfe\u5fdc\u65b9\u91dd<\/h2>\n
\n
\n
\n
Flutter \u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30a4\u30d9\u30f3\u30c8<\/h2>\n
\n
\n
paused<\/code>\u306b\u79fb\u884c\u3057\u3066\u3082\u304a\u304b\u3057\u304f\u306a\u3044\u524d\u63d0\u306b\u306a\u3063\u3066\u3044\u308b<\/li>\n<\/ul>\n<\/li>\n
\n
\n
\n
paused<\/code>\u30fb
resumed<\/code> \u306b\u9077\u79fb\u3059\u308b\u30a4\u30d9\u30f3\u30c8\u3092\u62fe\u3063\u3066\u3001\u300c\u5bfe\u5fdc\u65b9\u91dd\u300d\u306b\u66f8\u3044\u305f\u3053\u3068\u3092\u5b9f\u884c\u3059\u308c\u3070\u826f\u3055\u305d\u3046\u3067\u3059\u3002<\/p>\n
WidgetsBindingObserver<\/code>\u3092\u7d99\u627f\u3057\u3066\u3042\u3052\u3066\u3001
initState()<\/code>\u3067
addObserver()<\/code>\u3092\u5b9f\u884c\u3057\u3066\u3001
didChangeAppLifecycleState()<\/code>\u3092\u4e0a\u66f8\u304d\u3057\u3066\u3042\u3052\u308b\u3060\u3051\u3067\u3059\u3002<\/p>\n
class _TimerPageState extends State<TimerPage> with WidgetsBindingObserver {\n\n @override\n void initState() {\n super.initState();\n WidgetsBinding.instance.addObserver(this);\n }\n\n @override\n void dispose() {\n WidgetsBinding.instance.removeObserver(this);\n super.dispose();\n }\n\n@override\n void didChangeAppLifecycleState(AppLifecycleState state) {\n print(state); \/\/ \u597d\u304d\u306a\u51e6\u7406\u3092\u66f8\u304f\n }\n}<\/code><\/pre>\n
\u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\u306e\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u5bfe\u5fdc<\/h2>\n
\n
import 'dart:async';\n\nimport 'package:flutter\/material.dart';\nimport 'package:flutter_local_notifications\/flutter_local_notifications.dart';\nimport 'package:intl\/intl.dart';\nimport 'package:timezone\/data\/latest.dart' as tz;\nimport 'package:timezone\/timezone.dart' as tz;\n\nvoid main() async {\n _setupTimeZone();\n runApp(TimerApp());\n}\n\n\/\/ \u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u8a2d\u5b9a\u3059\u308b\nFuture<void> _setupTimeZone() async {\n tz.initializeTimeZones();\n var tokyo = tz.getLocation('Asia\/Tokyo');\n tz.setLocalLocation(tokyo);\n}\n\n\/\/\/ \u30bf\u30a4\u30de\u30fc\u30a2\u30d7\u30ea\nclass TimerApp extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return MaterialApp(\n title: 'Life cycle Event Sample Timer',\n theme: ThemeData(\n primarySwatch: Colors.blue,\n ),\n home: TimerPage(title: 'Life cycle Event Sample Timer'),\n );\n }\n}\n\n\/\/\/ \u30bf\u30a4\u30de\u30fc\u30da\u30fc\u30b8\nclass TimerPage extends StatefulWidget {\n TimerPage({Key key, this.title}) : super(key: key);\n final String title;\n @override\n _TimerPageState createState() => _TimerPageState();\n}\n\n\/\/\/ \u30bf\u30a4\u30de\u30fc\u30da\u30fc\u30b8\u306e\u72b6\u614b\u3092\u7ba1\u7406\u3059\u308b\u30af\u30e9\u30b9\nclass _TimerPageState extends State<TimerPage> with WidgetsBindingObserver {\n final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();\n Timer _timer; \/\/ \u30bf\u30a4\u30de\u30fc\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\n DateTime _time = DateTime.utc(0, 0, 0).add(Duration(seconds: 10)); \/\/ \u30bf\u30a4\u30de\u30fc\u3067\u7ba1\u7406\u3057\u3066\u3044\u308b\u6642\u9593\u300210\u79d2\u3092\u30ab\u30a6\u30f3\u30c8\u30c0\u30a6\u30f3\u3059\u308b\u8a2d\u5b9a\n bool _isTimerPaused = false; \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u969b\u306b\u30bf\u30a4\u30de\u30fc\u304c\u3082\u3068\u3082\u3068\u8d77\u52d5\u4e2d\u3067\u3001\u505c\u6b62\u3057\u305f\u304b\u3069\u3046\u304b\n DateTime _pausedTime; \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u6642\u9593\n int _notificationId; \/\/ \u901a\u77e5ID\n\n \/\/\/ \u521d\u671f\u5316\u51e6\u7406\n @override\n void initState() {\n super.initState();\n WidgetsBinding.instance.addObserver(this);\n }\n\n \/\/\/ \u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u304c\u5909\u66f4\u3055\u308c\u305f\u969b\u306b\u547c\u3073\u51fa\u3055\u308c\u308b\u95a2\u6570\u3092override\u3057\u3066\u3001\u5909\u66f4\u3092\u691c\u77e5\n @override\n void didChangeAppLifecycleState(AppLifecycleState state) {\n if (state == AppLifecycleState.paused) {\n \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u6642\n setState(_handleOnPaused);\n } else if (state == AppLifecycleState.resumed) {\n \/\/ \u30d5\u30a9\u30a2\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u5fa9\u5e30\u3057\u305f\u6642\n setState(_handleOnResumed);\n }\n }\n\n \/\/\/ \u30a2\u30d7\u30ea\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u969b\u306e\u30cf\u30f3\u30c9\u30e9\n void _handleOnPaused() {\n if (_timer.isActive) {\n _isTimerPaused = true;\n _timer.cancel(); \/\/ \u30bf\u30a4\u30de\u30fc\u3092\u505c\u6b62\u3059\u308b\n }\n _pausedTime = DateTime.now(); \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u9077\u79fb\u3057\u305f\u6642\u9593\u3092\u8a18\u9332\n _notificationId = _scheduleLocalNotification(_time.difference(DateTime.utc(0, 0, 0))); \/\/ \u30ed\u30fc\u30ab\u30eb\u901a\u77e5\u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u767b\u9332\n }\n\n \/\/\/ \u30a2\u30d7\u30ea\u304c\u30d5\u30a9\u30a2\u30b0\u30e9\u30a6\u30f3\u30c9\u306b\u5fa9\u5e30\u3057\u305f\u969b\u306e\u30cf\u30f3\u30c9\u30e9\n void _handleOnResumed() {\n if (_isTimerPaused == null) return; \/\/ \u30bf\u30a4\u30de\u30fc\u304c\u52d5\u3044\u3066\u306a\u3051\u308c\u3070\u4f55\u3082\u3057\u306a\u3044\n Duration backgroundDuration = DateTime.now().difference(_pausedTime); \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u306e\u7d4c\u904e\u6642\u9593\n \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u306e\u7d4c\u904e\u6642\u9593\u304c\u7d42\u4e86\u4e88\u5b9a\u3092\u8d85\u3048\u3066\u3044\u305f\u5834\u5408\uff08\u3053\u306e\u5834\u5408\u306f\u901a\u77e5\u5b9f\u884c\u6e08\u307f\u306e\u306f\u305a\uff09\n if (_time.difference(DateTime.utc(0, 0, 0)).compareTo(backgroundDuration) < 0) {\n _time = DateTime.utc(0, 0, 0); \/\/ \u6642\u9593\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b\n } else {\n _time = _time.add(-backgroundDuration); \/\/ \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u7d4c\u904e\u6642\u9593\u5206\u6642\u9593\u3092\u9032\u3081\u308b\n _startTimer(); \/\/ \u30bf\u30a4\u30de\u30fc\u3092\u518d\u958b\u3059\u308b\n }\n if (_notificationId != null) flutterLocalNotificationsPlugin.cancel(_notificationId); \/\/ \u901a\u77e5\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\n _isTimerPaused = false; \/\/ \u30ea\u30bb\u30c3\u30c8\n _notificationId = null; \/\/ \u30ea\u30bb\u30c3\u30c8\n _pausedTime = null;\n }\n\n \/\/ \u30bf\u30a4\u30de\u30fc\u3092\u958b\u59cb\u3059\u308b\n void _startTimer() {\n _timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {\n setState(() {\n _time = _time.add(Duration(seconds: -1));\n _handleTimeIsOver();\n });\n }); \/\/ 1\u79d2\u305a\u3064\u6642\u9593\u3092\u6e1b\u3089\u3059\n }\n\n \/\/ \u6642\u9593\u304c\u30bc\u30ed\u306b\u306a\u3063\u305f\u3089\u30bf\u30a4\u30de\u30fc\u3092\u6b62\u3081\u308b\n void _handleTimeIsOver() {\n if (_timer != null && _timer.isActive && _time != null && _time == DateTime.utc(0, 0, 0)) {\n _timer.cancel();\n }\n }\n\n \/\/\/ \u30bf\u30a4\u30de\u30fc\u7d42\u4e86\u3092\u30ed\u30fc\u30ab\u30eb\u901a\u77e5\n int _scheduleLocalNotification(Duration duration) {\n print('notification scheduled.');\n flutterLocalNotificationsPlugin.initialize(\n InitializationSettings(android: AndroidInitializationSettings('app_icon'), iOS: IOSInitializationSettings()), \/\/ app_icon.png\u3092\u914d\u7f6e\n );\n int notificationId = DateTime.now().hashCode;\n flutterLocalNotificationsPlugin.zonedSchedule(\n notificationId,\n 'Time is over',\n '',\n tz.TZDateTime.now(tz.local).add(duration),\n NotificationDetails(\n android: AndroidNotificationDetails('your channel id', 'your channel name', 'your channel description',\n importance: Importance.max, priority: Priority.high),\n iOS: IOSNotificationDetails()),\n uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime);\n return notificationId;\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n body: Column(mainAxisAlignment: MainAxisAlignment.center, children: [\n Text(\n DateFormat.Hms().format(_time),\n style: Theme.of(context).textTheme.headline2,\n ),\n Row(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n FloatingActionButton(\n onPressed: () {\n if (_timer != null && _timer.isActive) _timer.cancel();\n },\n child: Text("Stop"),\n ),\n FloatingActionButton(\n onPressed: _startTimer,\n child: Text("Start"),\n ),\n ],\n )\n ]));\n }\n}<\/code><\/pre>\n
paused<\/code>\u3068
resumed<\/code>\u306b\u300c\u5bfe\u5fdc\u65b9\u91dd\u300d\u3067\u66f8\u3044\u305f\u5185\u5bb9\u3092\u5b9f\u88c5\u3057\u3066\u3044\u308b\u3060\u3051\u306a\u306e\u3067\u3001\u8aac\u660e\u306f\u5272\u611b\u3057\u307e\u3059\u3002\u30b3\u30e1\u30f3\u30c8\u3092\u591a\u3081\u306b\u66f8\u3044\u3066\u308b\u306e\u3067\u3001 \u8208\u5473\u304c\u3042\u308b\u65b9\u306f\u53c2\u8003\u306b\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002
\n\u624b\u5143\u3067\u52d5\u304b\u3057\u3066\u307f\u305f\u3044\u65b9\u306f\u3001\u5b9f\u969b\u52d5\u304b\u3057\u305f \u30bd\u30fc\u30b9\u30b3\u30fc\u30c9<\/a> \u3082\u516c\u958b\u3057\u3066\u307e\u3059\u3002<\/p>\n\u59a5\u5354\u3057\u305f\u30dd\u30a4\u30f3\u30c8<\/h2>\n
\u3055\u3044\u3054\u306b<\/h2>\n
\n\u5c11\u3057\u59a5\u5354\u3057\u305f\u70b9\u306f\u3042\u308b\u3082\u306e\u306e\u3001Flutter\u304a\u3088\u3073\u30d7\u30e9\u30b0\u30a4\u30f3\u304c\u63d0\u4f9b\u3057\u3066\u304f\u308c\u3066\u3044\u308b\u7bc4\u56f2\u5185\u3067\u3001\u30b7\u30f3\u30d7\u30eb\u306b\u5b9f\u73fe\u3067\u304d\u305f\u306e\u304c\u3088\u304b\u3063\u305f\u3067\u3059\u3002<\/p>\n