From c6a43b7c83c24bb335d0c5ddc208f835ff038e1f Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Sun, 3 Jul 2022 18:25:21 +1200 Subject: [PATCH] Pause attempt at using WorkManager --- Alarm.tsx | 4 +- Home.tsx | 18 +----- android/app/build.gradle | 18 ++++++ android/app/src/main/AndroidManifest.xml | 1 + .../main/java/com/massive/AlarmModule.java | 53 +++++++++++++++ .../main/java/com/massive/AlarmPackage.java | 32 ++++++++++ .../main/java/com/massive/AlarmWorker.java | 64 +++++++++++++++++++ .../java/com/massive/MainApplication.java | 1 + 8 files changed, 173 insertions(+), 18 deletions(-) create mode 100644 android/app/src/main/java/com/massive/AlarmModule.java create mode 100644 android/app/src/main/java/com/massive/AlarmPackage.java create mode 100644 android/app/src/main/java/com/massive/AlarmWorker.java diff --git a/Alarm.tsx b/Alarm.tsx index 7b70e1d..ea9408b 100644 --- a/Alarm.tsx +++ b/Alarm.tsx @@ -15,14 +15,14 @@ export default function Alarm({onClose}: {onClose: () => void}) { if (ms <= 0) return; let secondsLeft = ms / 1000; console.log({secondsLeft}); - setSeconds(secondsLeft % 60); + setSeconds(Math.floor(secondsLeft % 60)); setMinutes(Math.floor(secondsLeft / 60)); intervalId = setInterval(() => { console.log({seconds, secondsLeft}); secondsLeft--; if (secondsLeft <= 0) return clearInterval(intervalId); - setSeconds(Math.ceil(secondsLeft % 60)); + setSeconds(Math.floor(secondsLeft % 60)); setMinutes(Math.floor(secondsLeft / 60)); }, 1000); }); diff --git a/Home.tsx b/Home.tsx index 2ad7929..aa95202 100644 --- a/Home.tsx +++ b/Home.tsx @@ -3,19 +3,17 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack'; import React, {useEffect, useState} from 'react'; import { FlatList, + NativeModules, SafeAreaView, StyleSheet, TextInput, Vibration, View, } from 'react-native'; -import BackgroundTimer from 'react-native-background-timer'; import {Button, List} from 'react-native-paper'; -import PushNotification from 'react-native-push-notification'; import Sound from 'react-native-sound'; import Alarm from './Alarm'; import {RootStackParamList} from './App'; -import {ALARM} from './channels'; import {getDb} from './db'; import EditSet from './EditSet'; @@ -84,20 +82,8 @@ export default function Home({ const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000; const when = new Date(); when.setTime(when.getTime() + milliseconds); + NativeModules.AlarmModule.timer(milliseconds); await AsyncStorage.setItem('nextAlarm', when.toISOString()); - const timeoutId = BackgroundTimer.setTimeout(() => { - alarm.play(_onEnd => Vibration.cancel()); - Vibration.vibrate([0, 400, 600], /*repeat=*/ true); - PushNotification.localNotification({ - message: 'Timer up', - channelId: ALARM, - vibrate: true, - }); - }, Number(milliseconds)); - BackgroundTimer.clearTimeout( - Number(await AsyncStorage.getItem('timeoutId')), - ); - await AsyncStorage.setItem('timeoutId', timeoutId.toString()); }; const close = () => { diff --git a/android/app/build.gradle b/android/app/build.gradle index 063040e..461162d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -264,6 +264,24 @@ android { } dependencies { + def work_version = "2.7.1" + // (Java only) + implementation "androidx.work:work-runtime:$work_version" + + // Kotlin + coroutines + implementation "androidx.work:work-runtime-ktx:$work_version" + + // optional - RxJava2 support + implementation "androidx.work:work-rxjava2:$work_version" + + // optional - GCMNetworkManager support + implementation "androidx.work:work-gcm:$work_version" + + // optional - Test helpers + androidTestImplementation "androidx.work:work-testing:$work_version" + // optional - Multiprocess support + implementation "androidx.work:work-multiprocess:$work_version" + implementation fileTree(dir: "libs", include: ["*.jar"]) //noinspection GradleDynamicVersion diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 96176d3..989f592 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ + createViewManagers(@NonNull ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @NonNull + @Override + public List createNativeModules( + @NonNull ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + + modules.add(new AlarmModule(reactContext)); + + return modules; + } + +} diff --git a/android/app/src/main/java/com/massive/AlarmWorker.java b/android/app/src/main/java/com/massive/AlarmWorker.java new file mode 100644 index 0000000..b6c47da --- /dev/null +++ b/android/app/src/main/java/com/massive/AlarmWorker.java @@ -0,0 +1,64 @@ +package com.massive; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.media.MediaPlayer; +import android.os.Build; +import android.os.Vibrator; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; +import androidx.work.Worker; +import androidx.work.WorkerParameters; + +public class AlarmWorker extends Worker { + private static final String CHANNEL_ID = "MassiveAlarms"; + + public AlarmWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { + super(context, workerParams); + } + + @NonNull + @Override + public Result doWork() { + Log.d("AlarmWorker", "Doing work..."); + createNotificationChannel(); + Intent intent = new Intent(getApplicationContext(), AlarmModule.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_IMMUTABLE); + NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID) + .setSmallIcon(R.drawable.autofill_inline_suggestion_chip_background) + .setContentTitle("Rest complete.") + .setContentText("Break time is over!") + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .setPriority(NotificationCompat.PRIORITY_DEFAULT); + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext()); + notificationManager.notify(1, builder.build()); + MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.argon); + mediaPlayer.start(); // no need to call prepare(); create() does that for you + Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE); + vibrator.vibrate(400); + return Result.success(); + } + + private void createNotificationChannel() { + Log.d("AlarmWorker", "Creating notification channel..."); + // Create the NotificationChannel, but only on API 26+ because + // the NotificationChannel class is new and not in the support library + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_DEFAULT; + NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "MassiveAlarms", importance); + channel.setDescription("Alarms for the Massive application"); + // Register the channel with the system; you can't change the importance + // or other notification behaviors after this + NotificationManager notificationManager = getApplicationContext().getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(channel); + } + } +} diff --git a/android/app/src/main/java/com/massive/MainApplication.java b/android/app/src/main/java/com/massive/MainApplication.java index 6b40f3a..3c5816b 100644 --- a/android/app/src/main/java/com/massive/MainApplication.java +++ b/android/app/src/main/java/com/massive/MainApplication.java @@ -28,6 +28,7 @@ public class MainApplication extends Application implements ReactApplication { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); packages.add(new SQLitePluginPackage()); + packages.add(new AlarmPackage()); return packages; }