Fix alarm sound and vibration
|
@ -28,6 +28,8 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:exported="true" android:process=":remote" android:name=".AlarmActivity" />
|
||||
<receiver android:exported="true" android:process=":remote" android:name=".MyBroadcastReceiver" />
|
||||
<service android:name=".AlarmService" android:exported="true" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
BIN
android/app/src/main/ic_launcher-playstore.png
Normal file
After Width: | Height: | Size: 15 KiB |
33
android/app/src/main/java/com/massive/AlarmActivity.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package com.massive;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class AlarmActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
Log.d("AlarmActivity", "Call to AlarmActivity");
|
||||
super.onCreate(savedInstanceState);
|
||||
Context context = getApplicationContext();
|
||||
context.stopService(new Intent(context, AlarmService.class));
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
|
||||
return super.onCreateView(name, context, attrs);
|
||||
}
|
||||
}
|
|
@ -62,4 +62,12 @@ public class AlarmModule extends ReactContextBaseJavaModule {
|
|||
AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + milliseconds, pendingIntent);
|
||||
alarmManager.setAlarmClock(info, pendingIntent);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public void stop() {
|
||||
Log.d("AlarmModule", "Request to stop timer.");
|
||||
Intent intent = new Intent(getReactApplicationContext(), MyBroadcastReceiver.class);
|
||||
intent.setAction("stop");
|
||||
getReactApplicationContext().startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
|
60
android/app/src/main/java/com/massive/AlarmService.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
package com.massive;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class AlarmService extends Service implements MediaPlayer.OnPreparedListener {
|
||||
private static final String ACTION_PLAY = "com.example.action.PLAY";
|
||||
MediaPlayer mediaPlayer = null;
|
||||
private Vibrator vibrator;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.d("AlarmService", "Starting alarm: " + intent.getAction());
|
||||
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.argon);
|
||||
mediaPlayer.start();
|
||||
mediaPlayer.setOnCompletionListener(mediaPlayer -> vibrator.cancel());
|
||||
long[] pattern = {0, 300, 1300, 300, 1300, 300};
|
||||
vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.build();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes);
|
||||
} else {
|
||||
vibrator.vibrate(pattern, 1, audioAttributes);
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Called when MediaPlayer is ready */
|
||||
public void onPrepared(MediaPlayer player) {
|
||||
player.start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mediaPlayer != null) mediaPlayer.release();
|
||||
if (vibrator != null) vibrator.cancel();
|
||||
}
|
||||
}
|
|
@ -6,12 +6,10 @@ 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;
|
||||
|
@ -21,39 +19,12 @@ 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)
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@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) {
|
||||
String action = intent.getAction();
|
||||
Log.d("MyBroadcastReceiver", "Action: " + action);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
int importance = NotificationManager.IMPORTANCE_HIGH;
|
||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance);
|
||||
|
@ -61,6 +32,24 @@ public class MyBroadcastReceiver extends BroadcastReceiver {
|
|||
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
context.startService(new Intent(context, AlarmService.class));
|
||||
Intent contentIntent = new Intent(context.getApplicationContext(), AlarmActivity.class);
|
||||
PendingIntent pendingContent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE);
|
||||
long[] pattern = {0, 100, 1000, 200, 2000};
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.rn_edit_text_material)
|
||||
.setContentTitle("Rest")
|
||||
.setContentText("Break times over!")
|
||||
.setContentIntent(pendingContent)
|
||||
.setAutoCancel(true)
|
||||
.setVibrate(pattern)
|
||||
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
notificationManager.notify(ALARM_ID, builder.build());
|
||||
}
|
||||
|
||||
private void vibrate(Context context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
74
android/app/src/main/res/drawable/ic_launcher_background.xml
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
android:height="108dp"
|
||||
android:width="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
</vector>
|
15
android/app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<group android:scaleX="1.2375"
|
||||
android:scaleY="1.2375"
|
||||
android:translateX="24.3"
|
||||
android:translateY="24.3">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M27.5,43.8 L25.4,41.7 32.5,34.6 13.4,15.5 6.3,22.6 4.2,20.5 7,17.6 4.2,14.8 8.45,10.55 6.35,8.45 8.45,6.35 10.6,8.4 14.8,4.2 17.6,7 20.5,4.2 22.6,6.3 15.5,13.4 34.6,32.5 41.7,25.4 43.8,27.5 41,30.4 43.8,33.2 39.5,37.5 41.6,39.6 39.5,41.7 37.4,39.6 33.2,43.8 30.4,41Z"/>
|
||||
</group>
|
||||
</vector>
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#1D1F21</color>
|
||||
</resources>
|