diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 989f592..e87e005 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,29 +1,33 @@
+ package="com.massive">
-
-
+
+
+
-
-
-
-
-
-
-
+ android:roundIcon="@mipmap/ic_launcher_round"
+ android:theme="@style/AppTheme"
+ android:dataExtractionRules="@xml/data_extraction_rules">
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/java/com/massive/AlarmModule.java b/android/app/src/main/java/com/massive/AlarmModule.java
index d65765b..600168d 100644
--- a/android/app/src/main/java/com/massive/AlarmModule.java
+++ b/android/app/src/main/java/com/massive/AlarmModule.java
@@ -1,12 +1,19 @@
package com.massive; // replace com.your-app-name with your app’s name
+import static android.content.Context.ALARM_SERVICE;
+
+import android.app.AlarmManager;
import android.app.Notification;
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.SystemClock;
import android.util.Log;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@@ -24,6 +31,8 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.time.Duration;
+import java.util.Calendar;
+import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
@@ -42,12 +51,15 @@ public class AlarmModule extends ReactContextBaseJavaModule {
@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);
+ Intent intent = new Intent(getReactApplicationContext(), MyBroadcastReceiver.class);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ getReactApplicationContext(), 69, intent, PendingIntent.FLAG_IMMUTABLE);
+ AlarmManager alarmManager = (AlarmManager) getReactApplicationContext().getSystemService(ALARM_SERVICE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ Log.d("AlarmModule", "Can schedule: " + alarmManager.canScheduleExactAlarms());
+ }
+ AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + milliseconds, pendingIntent);
+ alarmManager.setAlarmClock(info, pendingIntent);
}
}
diff --git a/android/app/src/main/java/com/massive/AlarmWorker.java b/android/app/src/main/java/com/massive/AlarmWorker.java
deleted file mode 100644
index b6c47da..0000000
--- a/android/app/src/main/java/com/massive/AlarmWorker.java
+++ /dev/null
@@ -1,64 +0,0 @@
-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/MyBroadcastReceiver.java b/android/app/src/main/java/com/massive/MyBroadcastReceiver.java
new file mode 100644
index 0000000..33cc1f8
--- /dev/null
+++ b/android/app/src/main/java/com/massive/MyBroadcastReceiver.java
@@ -0,0 +1,67 @@
+package com.massive;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.os.Build;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.annotation.RequiresApi;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
+
+public class MyBroadcastReceiver extends BroadcastReceiver {
+ private static final String CHANNEL_ID = "MassiveAlarm";
+ private static final int ALARM_ID = 59;
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d("MyBroadcastReceiver", "Received intent for BroadcastReceiver.");
+ long[] pattern = {0, 300, 200, 300, 200};
+ int[] amplitudes = {VibrationEffect.DEFAULT_AMPLITUDE, VibrationEffect.DEFAULT_AMPLITUDE, VibrationEffect.DEFAULT_AMPLITUDE, VibrationEffect.DEFAULT_AMPLITUDE, VibrationEffect.DEFAULT_AMPLITUDE};
+ Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ vibrator.vibrate(VibrationEffect.createWaveform(pattern, amplitudes, 0));
+ } else {
+ //deprecated in API 26
+ vibrator.vibrate(500);
+ }
+ createNotificationChannel(context);
+
+ Intent contentIntent = new Intent(context.getApplicationContext(), MainActivity.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE);
+
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
+ .setSmallIcon(R.drawable.rn_edit_text_material)
+ .setContentTitle("Rest")
+ .setContentText("Break times over!")
+ .setContentIntent(pendingIntent)
+ .setAutoCancel(true)
+ .setCategory(NotificationCompat.CATEGORY_ALARM)
+ .setPriority(NotificationCompat.PRIORITY_HIGH);
+ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
+ notificationManager.notify(ALARM_ID, builder.build());
+ MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.argon);
+ mediaPlayer.start();
+ }
+
+ private void createNotificationChannel(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ int importance = NotificationManager.IMPORTANCE_HIGH;
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance);
+ channel.setDescription("Alarms for rest timings.");
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(channel);
+ }
+ }
+}
+
+
diff --git a/android/app/src/main/res/xml/data_extraction_rules.xml b/android/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..8b570f1
--- /dev/null
+++ b/android/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 60538c7..30acc9f 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"@react-native-async-storage/async-storage": "^1.17.7",
"@react-native-community/push-notification-ios": "^1.10.1",
"@react-navigation/bottom-tabs": "^6.3.1",
+ "@react-navigation/material-top-tabs": "^6.2.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "^6.6.2",
"@types/react-native-background-timer": "^2.0.0",
@@ -25,6 +26,7 @@
"react-native": "0.69.1",
"react-native-background-timer": "^2.4.1",
"react-native-gesture-handler": "^2.5.0",
+ "react-native-pager-view": "^5.4.24",
"react-native-paper": "^4.12.2",
"react-native-push-notification": "^8.1.1",
"react-native-reanimated": "^2.9.0",
@@ -32,6 +34,7 @@
"react-native-screens": "^3.14.0",
"react-native-sound": "^0.11.2",
"react-native-sqlite-storage": "^6.0.1",
+ "react-native-tab-view": "^3.1.1",
"react-native-vector-icons": "^9.2.0"
},
"devDependencies": {
diff --git a/yarn.lock b/yarn.lock
index 24baeae..3a66bf1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1650,6 +1650,14 @@
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.3.tgz#9f56b650a9a1a8263a271628be7342c8121d1788"
integrity sha512-Lv2lR7si5gNME8dRsqz57d54m4FJtrwHRjNQLOyQO546ZxO+g864cSvoLC6hQedQU0+IJnPTsZiEI2hHqfpEpw==
+"@react-navigation/material-top-tabs@^6.2.1":
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/@react-navigation/material-top-tabs/-/material-top-tabs-6.2.1.tgz#747d17bd0138a7d50c791e9cce1adc350904f67d"
+ integrity sha512-fGy2+/7cUAyrZUPUhzKUttA4avK5Z2FrNk0LRI04hRlAVqs5DYpnaQGkegGeOGwKmnxaVCjCVPr+KoEroyqduw==
+ dependencies:
+ color "^3.1.3"
+ warn-once "^0.1.0"
+
"@react-navigation/native-stack@^6.6.2":
version "6.6.2"
resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.6.2.tgz#09e696ad72299872f4c5c1e5b1ad309869853628"
@@ -6676,6 +6684,11 @@ react-native-iphone-x-helper@^1.3.1:
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010"
integrity sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==
+react-native-pager-view@^5.4.24:
+ version "5.4.24"
+ resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-5.4.24.tgz#8626e757ddc55e41eca66d2f8a8a75aec54591ee"
+ integrity sha512-dRMB7i3B+mu4NCeIN6gqbR/kC/rr2wzqO0gisXDdJwJr78G24sWoTNpLEDFo3G8TFHY9nTMutVl5CUvkN2dp6g==
+
react-native-paper@^4.12.2:
version "4.12.2"
resolved "https://registry.yarnpkg.com/react-native-paper/-/react-native-paper-4.12.2.tgz#31ed8011afd994d54dd403ed0099295fc1616d26"
@@ -6727,6 +6740,11 @@ react-native-sqlite-storage@^6.0.1:
resolved "https://registry.yarnpkg.com/react-native-sqlite-storage/-/react-native-sqlite-storage-6.0.1.tgz#ce6a6b852f07abbea68658d5363818c8bef45dfb"
integrity sha512-1tDFjrint6X6qSYKf3gDyz+XB+X79jfiL6xTugKHPRtF0WvqMtVgdLuNqZunIXjNEvNtNVEbXaeZ6MsguFu00A==
+react-native-tab-view@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-3.1.1.tgz#1f8d7a835ab4f5b1b1407ec8dddc1053b53fa3c6"
+ integrity sha512-M5pRN6utQfytKWoKlKVzg5NbkYu308qNoW1khGTtEOTs1k14p2dHJ/BWOJoJYHKbPVUyZldbG9MFT7gUl4YHnw==
+
react-native-vector-icons@^9.2.0:
version "9.2.0"
resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz#3c0c82e95defd274d56363cbe8fead8d53167ebd"