Pause attempt at using WorkManager

This commit is contained in:
Brandon Presley 2022-07-03 18:25:21 +12:00
parent bb9a6c5f37
commit c6a43b7c83
8 changed files with 173 additions and 18 deletions

View File

@ -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);
});

View File

@ -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 = () => {

View File

@ -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

View File

@ -3,6 +3,7 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:name=".MainApplication"

View File

@ -0,0 +1,53 @@
package com.massive; // replace com.your-app-name with your apps name
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import androidx.work.WorkRequest;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.time.Duration;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
public class AlarmModule extends ReactContextBaseJavaModule {
AlarmModule(ReactApplicationContext context) {
super(context);
}
@NonNull
@Override
public String getName() {
return "AlarmModule";
}
@RequiresApi(api = Build.VERSION_CODES.O)
@ReactMethod(isBlockingSynchronousMethod = true)
public void timer(int milliseconds) {
WorkRequest request = new PeriodicWorkRequest.Builder(
AlarmWorker.class, milliseconds, TimeUnit.MILLISECONDS
)
.build();
Log.d("AlarmModule", "Queue alarm for " + milliseconds + " delay");
WorkManager.getInstance(getReactApplicationContext())
.enqueue(request);
}
}

View File

@ -0,0 +1,32 @@
package com.massive;
import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AlarmPackage implements ReactPackage {
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@NonNull
@Override
public List<NativeModule> createNativeModules(
@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new AlarmModule(reactContext));
return modules;
}
}

View File

@ -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);
}
}
}

View File

@ -28,6 +28,7 @@ public class MainApplication extends Application implements ReactApplication {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new SQLitePluginPackage());
packages.add(new AlarmPackage());
return packages;
}