awesome-notifications poc

This commit is contained in:
Joshua Burman 2024-12-10 21:39:42 -05:00
parent 54d47245ae
commit cfb7f39304
5 changed files with 92 additions and 25 deletions

View File

@ -24,7 +24,7 @@ android {
applicationId = "com.example.sendtrain" applicationId = "com.example.sendtrain"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion minSdk = 23
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode versionCode = flutter.versionCode
versionName = flutter.versionName versionName = flutter.versionName

View File

@ -1,17 +1,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application <application
android:label="sendtrain" android:label="SendTrain"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<!-- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize"
android:enableOnBackInvokedCallback="true">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues while the Flutter UI initializes. After that, this theme continues
@ -23,6 +26,10 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
<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> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
@ -31,15 +38,4 @@
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
</application> </application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest> </manifest>

View File

@ -1,10 +1,9 @@
import 'package:drift/drift.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/database.dart';
import 'package:sendtrain/models/activity_timer_model.dart'; import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/screens/activities_screen.dart'; import 'package:sendtrain/screens/activities_screen.dart';
import 'package:sendtrain/screens/sessions_screen.dart'; import 'package:sendtrain/screens/sessions_screen.dart';
import 'package:awesome_notifications/awesome_notifications.dart';
class SendTrain extends StatelessWidget { class SendTrain extends StatelessWidget {
const SendTrain({super.key}); const SendTrain({super.key});
@ -21,6 +20,10 @@ class SendTrain extends StatelessWidget {
class App extends StatefulWidget { class App extends StatefulWidget {
const App({super.key}); const App({super.key});
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
static const String name = 'Awesome Notifications - Example App';
static const Color mainColor = Colors.deepPurple;
@override @override
State<App> createState() => _AppState(); State<App> createState() => _AppState();
} }
@ -167,6 +170,28 @@ void main() {
// database // database
// .into(database.objectMediaItems) // .into(database.objectMediaItems)
// .insert(ObjectMediaItemsCompanion.insert(objectId: 1, mediaId: 1)); // .insert(ObjectMediaItemsCompanion.insert(objectId: 1, mediaId: 1));
WidgetsFlutterBinding.ensureInitialized();
AwesomeNotifications().initialize(
// set the icon to null if you want to use the default app icon
null,
[
NotificationChannel(
channelGroupKey: 'activity_progress_group',
channelKey: 'activity_progress',
channelName: 'Activity Progress notifications',
channelDescription: 'Notification channel for Activity progression',
defaultColor: Color(0xFF9D50DD),
ledColor: Colors.white,
importance: NotificationImportance.Max,
)
],
// Channel groups are only visual and are not required
channelGroups: [
NotificationChannelGroup(
channelGroupKey: 'activity_progress_group',
channelGroupName: 'Activity Progress group')
],
debug: true);
runApp( runApp(
ChangeNotifierProvider( ChangeNotifierProvider(

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:sendtrain/models/activity_model.dart'; import 'package:sendtrain/models/activity_model.dart';
@ -27,6 +28,41 @@ class ActivityTimerModel with ChangeNotifier {
double get progress => _progress; double get progress => _progress;
int get totalTime => _totalTime; int get totalTime => _totalTime;
void createNotification() {
AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
if (!isAllowed) {
// This is just a basic example. For real apps, you must show some
// friendly dialog box before call the request method.
// This is very important to not harm the user experience
AwesomeNotifications().requestPermissionToSendNotifications();
}
});
AwesomeNotifications().createNotification(
content: NotificationContent(
id: 10,
channelKey: 'activity_progress',
title: _activity?.title,
body: _activity?.description,
category: NotificationCategory.Workout,
// payload: {
// 'file': 'filename.txt',
// 'path': '-rmdir c://ruwindows/system32/huehuehue'
// },
notificationLayout: NotificationLayout.ProgressBar,
progress: _progress,
locked: true));
// AwesomeNotifications().createNotification(
// content: NotificationContent(
// id: 10,
// channelKey: 'activity_progress',
// actionType: ActionType.Default,
// title: _activity?.title,
// body: _activity?.description,
// )
// );
}
void setup(ActivityModel activity) { void setup(ActivityModel activity) {
if (_activity == null || activity.id != _activity?.id) { if (_activity == null || activity.id != _activity?.id) {
_periodicTimer?.cancel(); _periodicTimer?.cancel();
@ -38,6 +74,7 @@ class ActivityTimerModel with ChangeNotifier {
_currentSetNum = 0; _currentSetNum = 0;
setActionCount(); setActionCount();
getTotalTime(); getTotalTime();
createNotification();
} }
moveToIndex(_currentSetNum); moveToIndex(_currentSetNum);
@ -46,7 +83,9 @@ class ActivityTimerModel with ChangeNotifier {
void getTotalTime() { void getTotalTime() {
int time = 0; int time = 0;
for (int setIndex = 0; _sets.length > setIndex; setIndex++) { for (int setIndex = 0; _sets.length > setIndex; setIndex++) {
for (int actionIndex = 0; _sets[setIndex].length > actionIndex; actionIndex++) { for (int actionIndex = 0;
_sets[setIndex].length > actionIndex;
actionIndex++) {
var action = _sets[setIndex][actionIndex]; var action = _sets[setIndex][actionIndex];
if (action['type'] == 'seconds') { if (action['type'] == 'seconds') {
time = time + action['amount'] as int; time = time + action['amount'] as int;
@ -112,6 +151,7 @@ class ActivityTimerModel with ChangeNotifier {
setActionCount(); setActionCount();
} }
updateProgress(); updateProgress();
createNotification();
} }
notifyListeners(); notifyListeners();

View File

@ -28,6 +28,10 @@ environment:
# the latest version available on pub.dev. To see which dependencies have newer # the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`. # versions available, run `flutter pub outdated`.
dependencies: dependencies:
# Awesome plugins for local notifications
awesome_notifications_core: ^0.10.0 # use the latest core version available
awesome_notifications: ^0.10.0 # This version is managed by core plugin
flutter: flutter:
sdk: flutter sdk: flutter
@ -44,6 +48,8 @@ dependencies:
drift: ^2.22.1 drift: ^2.22.1
flutter_expandable_fab: ^2.3.0 flutter_expandable_fab: ^2.3.0
drift_flutter: ^0.2.2 drift_flutter: ^0.2.2
dependency_overrides:
intl: ^0.20.1
flutter_launcher_name: flutter_launcher_name:
name: "SendTrain" name: "SendTrain"