Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🆙 version to flutter local notification #1092

Merged
merged 13 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ dependencies {
implementation 'com.google.firebase:firebase-messaging:20.1.6'
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
// https://pub.dev/packages/flutter_local_notifications#-android-setup
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
// https://pub.dev/packages/flutter_local_notifications#-android-setup
// > There have been reports that enabling desugaring may result in a Flutter apps crashing on Android 12L and above. This would be an issue with Flutter itself, not the plugin. One possible fix is adding the WindowManager library as a dependency:
implementation 'androidx.window:window:1.0.0'
Expand Down
16 changes: 16 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@
android:resource="@xml/pilll_app_widget_info" />

</receiver>
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />

<!-- https://pub.dev/packages/flutter_local_notifications#-android-setup -->
<!-- Specify the following between the <application> tags so that the plugin can actually show the scheduled notification(s) -->
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>

<!-- https://pub.dev/packages/flutter_local_notifications#-android-setup -->
<!-- To use notification actions, specify <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" /> between the <application> tags so that the plugin can process the actions and trigger the appropriate callback(s) -->
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" />

<activity
android:name=".MainActivity"
Expand Down
4 changes: 3 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ buildscript {

dependencies {
classpath 'com.google.gms:google-services:4.3.5'
classpath 'com.android.tools.build:gradle:7.1.2'
// https://pub.dev/packages/flutter_local_notifications#-android-setup
// > Note that the plugin uses Android Gradle plugin 7.3.1 to leverage this functionality so to errr on the safe side, applications should aim to use the same version at a minimum. Using a higher version is also needed as at point, Android Studio bundled a newer version of the Java SDK that will only work with Gradle 7.3 or higher (see here for more details). For a Flutter project, this is specified in android/build.gradle and the main parts would look similar to the following
classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
Expand Down
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ SPEC CHECKSUMS:
FirebaseSessions: 96e7781e545929cde06dd91088ddbb0841391b43
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_app_badger: b87fc231847b03b92ce1412aa351842e7e97932f
flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_native_timezone: 5f05b2de06c9776b4cc70e1839f03de178394d22
Google-Mobile-Ads-SDK: e81e8b009a182dc8dd14951782efdbb30a5e4510
google_mobile_ads: 035df0d095e1a196b52e3c91534d0718d3dacf98
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:math';

import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:pilll/entity/firestore_id_generator.dart';
import 'package:pilll/entity/link_account_type.dart';
import 'package:pilll/utils/datetime/date_add.dart';
Expand Down Expand Up @@ -58,7 +57,7 @@ class InitialSettingState with _$InitialSettingState {
pillSheetTypes: pillSheetTypes,
reminderTimes: reminderTimes,
isOnReminder: isOnReminder,
timezoneDatabaseName: await FlutterNativeTimezone.getLocalTimezone(),
timezoneDatabaseName: null,
// BEGIN: Release function for trial user
pillSheetAppearanceMode: PillSheetAppearanceMode.date,
isAutomaticallyCreatePillSheet: true,
Expand Down
2 changes: 0 additions & 2 deletions lib/features/settings/provider.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:pilll/native/health_care.dart';
import 'package:riverpod/riverpod.dart';

final isHealthDataAvailableProvider = FutureProvider((ref) => isHealthDataAvailable());
final deviceTimezoneNameProvider = FutureProvider((ref) => FlutterNativeTimezone.getLocalTimezone());
62 changes: 14 additions & 48 deletions lib/features/settings/reminder_times_page.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import 'dart:async';

import 'package:async_value_group/async_value_group.dart';
import 'package:pilll/utils/analytics.dart';
import 'package:pilll/components/molecules/indicator.dart';
import 'package:pilll/provider/database.dart';
import 'package:pilll/features/settings/provider.dart';
import 'package:pilll/features/settings/timezone_setting_dialog.dart';
import 'package:pilll/entity/setting.codegen.dart';
import 'package:pilll/components/atoms/color.dart';
import 'package:pilll/components/atoms/font.dart';
Expand All @@ -28,27 +25,21 @@ class ReminderTimesPage extends HookConsumerWidget {
final setSetting = ref.watch(setSettingProvider);
final registerReminderLocalNotification = ref.watch(registerReminderLocalNotificationProvider);

return AsyncValueGroup.group2(
ref.watch(settingProvider),
ref.watch(deviceTimezoneNameProvider),
).when(
data: (data) {
final setting = data.t1;
final deviceTimezoneName = data.t2;
return ReminderTimesPageBody(
setting: setting,
deviceTimezoneName: deviceTimezoneName,
setSetting: setSetting,
registerReminderLocalNotification: registerReminderLocalNotification,
return ref.watch(settingProvider).when(
data: (setting) {
return ReminderTimesPageBody(
setting: setting,
setSetting: setSetting,
registerReminderLocalNotification: registerReminderLocalNotification,
);
},
error: (error, _) => UniversalErrorPage(
error: error,
child: null,
reload: () => ref.refresh(databaseProvider),
),
loading: () => const ScaffoldIndicator(),
);
},
error: (error, _) => UniversalErrorPage(
error: error,
child: null,
reload: () => ref.refresh(databaseProvider),
),
loading: () => const ScaffoldIndicator(),
);
}
}

Expand All @@ -63,14 +54,12 @@ extension ReminderTimesPageRoute on ReminderTimesPage {

class ReminderTimesPageBody extends StatelessWidget {
final Setting setting;
final String deviceTimezoneName;
final SetSetting setSetting;
final RegisterReminderLocalNotification registerReminderLocalNotification;

const ReminderTimesPageBody({
super.key,
required this.setting,
required this.deviceTimezoneName,
required this.setSetting,
required this.registerReminderLocalNotification,
});
Expand All @@ -88,29 +77,6 @@ class ReminderTimesPageBody extends StatelessWidget {
"通知時間",
style: TextStyle(color: TextColor.black),
),
actions: [
IconButton(
onPressed: () {
analytics.logEvent(name: "pressed_tz_setting_action");
showDialog(
context: context,
builder: (_) => TimezoneSettingDialog(
setting: setting,
deviceTimezoneName: deviceTimezoneName,
onDone: (tz) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 2),
content: Text("$tzに変更しました"),
),
);
},
),
);
},
icon: const Icon(Icons.timer_sharp, color: PilllColors.primary),
),
],
backgroundColor: PilllColors.background,
),
body: SafeArea(
Expand Down
3 changes: 0 additions & 3 deletions lib/provider/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:io';

import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:flutter/foundation.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:pilll/entity/remote_config_parameter.codegen.dart';
import 'package:pilll/provider/database.dart';
import 'package:pilll/entity/package.codegen.dart';
Expand Down Expand Up @@ -175,7 +174,6 @@ class SaveUserLaunchInfo {
final now = DateTime.now().toLocal();
final timeZoneName = now.timeZoneName;
final timeZoneOffset = now.timeZoneOffset;
final timeZoneDatabaseName = await FlutterNativeTimezone.getLocalTimezone();

// Package
final packageInfo = await PackageInfo.fromPlatform();
Expand Down Expand Up @@ -210,7 +208,6 @@ class SaveUserLaunchInfo {
},
"timezone": {
"name": timeZoneName,
"databaseName": timeZoneDatabaseName,
"offsetInHours": timeZoneOffset.inHours,
"offsetIsNegative": timeZoneOffset.isNegative,
},
Expand Down
3 changes: 1 addition & 2 deletions lib/utils/local_notification.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import 'package:pilll/utils/error_log.dart';
import 'package:riverpod/riverpod.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:flutter_native_timezone/flutter_native_timezone.dart';

// Reminder Notification
const actionIdentifier = "RECORD_PILL";
Expand All @@ -49,7 +48,7 @@ class LocalNotificationService {

static Future<void> setupTimeZone() async {
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(await FlutterNativeTimezone.getLocalTimezone()));
tz.setLocalLocation(tz.getLocation("Asia/Tokyo"));
}

Future<void> initialize() async {
Expand Down
15 changes: 5 additions & 10 deletions lib/utils/push_notification.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:pilll/utils/analytics.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:pilll/provider/user.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

Future<void> requestNotificationPermissions(RegisterRemotePushNotificationToken registerRemotePushNotificationToken) async {
await FirebaseMessaging.instance.requestPermission();
if (Platform.isIOS) {
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true, badge: true, sound: true);
}
listenNotificationEvents();
await FirebaseMessaging.instance.requestPermission(alert: true, badge: true, sound: true, announcement: true);
registerRemotePushNotificationToken(await FirebaseMessaging.instance.getToken());
}

void listenNotificationEvents() {
FirebaseMessaging.onMessageOpenedApp.listen((event) {
analytics.logEvent(name: "opened_from_notification_on_background");
debugPrint("onMessageOpenedApp: $event");
});
if (Platform.isAndroid) {
await AndroidFlutterLocalNotificationsPlugin().requestExactAlarmsPermission();
}
}
12 changes: 2 additions & 10 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,10 @@ packages:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: "501ed9d54f1c8c0535b7991bade36f9e7e3b45a2346401f03775c1ec7a3c06ae"
sha256: "55b9b229307a10974b26296ff29f2e132256ba4bd74266939118eaefa941cb00"
url: "https://pub.dev"
source: hosted
version: "15.1.2"
version: "16.3.3"
flutter_local_notifications_linux:
dependency: transitive
description:
Expand All @@ -507,14 +507,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_native_timezone:
dependency: "direct main"
description:
name: flutter_native_timezone
sha256: ed7bfb982f036243de1c068e269182a877100c994f05143c8b26a325e28c1b02
url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_riverpod:
dependency: transitive
description:
Expand Down
3 changes: 1 addition & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ dependencies:
cupertino_icons: ^1.0.6
flutter_app_badger: ^1.2.0
purchases_flutter: ^5.7.0
flutter_native_timezone: ^2.0.0
flutter_local_notifications: ^15.1.2
flutter_local_notifications: ^16.3.3
webview_flutter: ^4.7.0
collection: ^1.18.0
crypto:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:flutter/services.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:pilll/entity/firestore_id_generator.dart';
import 'package:pilll/entity/pill_sheet_modified_history.codegen.dart';
Expand Down Expand Up @@ -27,15 +26,10 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../helper/mock.mocks.dart';

void main() {
const MethodChannel timezoneChannel = MethodChannel('flutter_native_timezone');

setUp(() async {
TestWidgetsFlutterBinding.ensureInitialized();
SharedPreferences.setMockInitialValues({});

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(timezoneChannel, (MethodCall methodCall) async {
return 'Asia/Tokyo';
});
analytics = MockAnalytics();
errorLogger = MockErrorLogger();

Expand All @@ -45,9 +39,6 @@ void main() {
localNotificationService = mockLocalNotificationService;
});

tearDown(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(timezoneChannel, null);
});
group("#selectedFirstPillSheetType", () {
test("when first selected", () {
final batchFactory = MockBatchFactory();
Expand Down
10 changes: 0 additions & 10 deletions test/features/initial_setting/initial_setting_state_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:flutter/services.dart';
import 'package:pilll/entity/firestore_id_generator.dart';
import 'package:pilll/features/initial_setting/initial_setting_state.codegen.dart';
import 'package:pilll/entity/pill_sheet.codegen.dart';
Expand All @@ -11,20 +10,11 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../helper/mock.mocks.dart';

void main() {
const MethodChannel timezoneChannel = MethodChannel('flutter_native_timezone');

setUp(() {
TestWidgetsFlutterBinding.ensureInitialized();
SharedPreferences.setMockInitialValues({});

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(timezoneChannel, (MethodCall methodCall) async {
return 'Asia/Tokyo';
});
});

tearDown(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(timezoneChannel, null);
});
group("#InitialSettingState.buildPillSheet", () {
test("it is builded pillSheet.gropuIndex == todayPillNumber.pageIndex ", () {
final mockTodayRepository = MockTodayService();
Expand Down
3 changes: 0 additions & 3 deletions test/features/settings/reminder_times_widget_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:pilll/features/settings/provider.dart';
import 'package:pilll/entity/pill_sheet_type.dart';
import 'package:pilll/entity/setting.codegen.dart';
import 'package:pilll/features/settings/reminder_times_page.dart';
Expand Down Expand Up @@ -39,7 +38,6 @@ void main() {
ProviderScope(
overrides: [
settingProvider.overrideWith((ref) => Stream.value(setting)),
deviceTimezoneNameProvider.overrideWith((ref) => Future.value("Asia/Tokyo")),
setSettingProvider.overrideWith((ref) => MockSetSetting()),
],
child: const MaterialApp(home: ReminderTimesPage()),
Expand All @@ -66,7 +64,6 @@ void main() {
ProviderScope(
overrides: [
settingProvider.overrideWith((ref) => Stream.value(setting)),
deviceTimezoneNameProvider.overrideWith((ref) => Future.value("Asia/Tokyo")),
setSettingProvider.overrideWith((ref) => MockSetSetting()),
],
child: const MaterialApp(home: ReminderTimesPage()),
Expand Down
Loading