Use sqlite in Android code for alarm settings

Closes #129
This commit is contained in:
Brandon Presley 2023-01-02 18:54:35 +13:00
parent bafdecd3e3
commit a2721e9f12
6 changed files with 65 additions and 45 deletions

View File

@ -52,9 +52,7 @@ export default function EditSet() {
const first = await setRepo.findOne({where: {name: value}})
const milliseconds =
(first?.minutes ?? 3) * 60 * 1000 + (first?.seconds ?? 0) * 1000
const {vibrate, sound, noSound} = settings
const args = [milliseconds, vibrate, sound, noSound]
NativeModules.AlarmModule.timer(...args)
NativeModules.AlarmModule.timer(milliseconds)
},
[settings],
)

View File

@ -100,9 +100,7 @@ export default function StartPlan() {
if (!settings.alarm) return
const milliseconds =
Number(best.minutes) * 60 * 1000 + Number(best.seconds) * 1000
const {vibrate, sound, noSound} = settings
const args = [milliseconds, vibrate, sound, noSound]
NativeModules.AlarmModule.timer(...args)
NativeModules.AlarmModule.timer(milliseconds)
}
return (

View File

@ -32,8 +32,7 @@ export default function TimerPage() {
const add = async () => {
console.log(`${TimerPage.name}.add:`, settings)
const params = [settings.vibrate, settings.sound, settings.noSound]
NativeModules.AlarmModule.add(...params)
NativeModules.AlarmModule.add()
}
const progress = useMemo(() => {

View File

@ -19,7 +19,7 @@ import kotlin.math.floor
class AlarmModule constructor(context: ReactApplicationContext?) :
ReactContextBaseJavaModule(context) {
var countdownTimer: CountDownTimer? = null
private var countdownTimer: CountDownTimer? = null
var currentMs: Long = 0
var running = false
@ -38,11 +38,7 @@ class AlarmModule constructor(context: ReactApplicationContext?) :
private val addReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context?, intent: Intent?) {
val vibrate = intent?.extras?.getBoolean("vibrate") == true
val sound = intent?.extras?.getString("sound")
val noSound = intent?.extras?.getBoolean("noSound") == true
Log.d("AlarmModule", "vibrate=$vibrate,sound=$sound,noSound=$noSound")
add(vibrate, sound, noSound)
add()
}
}
@ -59,11 +55,11 @@ class AlarmModule constructor(context: ReactApplicationContext?) :
@RequiresApi(api = Build.VERSION_CODES.O)
@ReactMethod
fun add(vibrate: Boolean, sound: String?, noSound: Boolean = false) {
fun add() {
Log.d("AlarmModule", "Add 1 min to alarm.")
countdownTimer?.cancel()
val newMs = if (running) currentMs.toInt().plus(60000) else 60000
countdownTimer = getTimer(newMs, vibrate, sound, noSound)
countdownTimer = getTimer(newMs)
countdownTimer?.start()
running = true
val manager = getManager()
@ -94,14 +90,14 @@ class AlarmModule constructor(context: ReactApplicationContext?) :
@RequiresApi(api = Build.VERSION_CODES.O)
@ReactMethod
fun timer(milliseconds: Int, vibrate: Boolean, sound: String?, noSound: Boolean = false) {
fun timer(milliseconds: Int) {
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
val manager = getManager()
manager.cancel(NOTIFICATION_ID_DONE)
val intent = Intent(reactApplicationContext, AlarmService::class.java)
reactApplicationContext.stopService(intent)
countdownTimer?.cancel()
countdownTimer = getTimer(milliseconds, vibrate, sound, noSound)
countdownTimer = getTimer(milliseconds)
countdownTimer?.start()
running = true
}
@ -109,11 +105,8 @@ class AlarmModule constructor(context: ReactApplicationContext?) :
@RequiresApi(Build.VERSION_CODES.M)
private fun getTimer(
endMs: Int,
vibrate: Boolean,
sound: String?,
noSound: Boolean
): CountDownTimer {
val builder = getBuilder(vibrate, sound, noSound)
val builder = getBuilder()
return object : CountDownTimer(endMs.toLong(), 1000) {
@RequiresApi(Build.VERSION_CODES.O)
override fun onTick(current: Long) {
@ -156,12 +149,7 @@ class AlarmModule constructor(context: ReactApplicationContext?) :
val manager = getManager()
manager.notify(NOTIFICATION_ID_DONE, builder.build())
manager.cancel(NOTIFICATION_ID_PENDING)
Log.d("AlarmModule", "Finished: vibrate=$vibrate,sound=$sound,noSound=$noSound")
val alarmIntent = Intent(context, AlarmService::class.java).apply {
putExtra("vibrate", vibrate)
putExtra("sound", sound)
putExtra("noSound", noSound)
}
val alarmIntent = Intent(context, AlarmService::class.java)
context.startService(alarmIntent)
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
@ -175,20 +163,13 @@ class AlarmModule constructor(context: ReactApplicationContext?) :
@SuppressLint("UnspecifiedImmutableFlag")
@RequiresApi(Build.VERSION_CODES.M)
private fun getBuilder(
vibrate: Boolean,
sound: String?,
noSound: Boolean
): NotificationCompat.Builder {
private fun getBuilder(): NotificationCompat.Builder {
val context = reactApplicationContext
val contentIntent = Intent(context, MainActivity::class.java)
val pendingContent =
PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
val addBroadcast = Intent(ADD_BROADCAST).apply {
setPackage(reactApplicationContext.packageName)
putExtra("vibrate", vibrate)
putExtra("sound", sound)
putExtra("noSound", noSound)
}
val pendingAdd =
PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE)

View File

@ -1,27 +1,44 @@
package com.massive
import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.media.MediaPlayer.OnPreparedListener
import android.media.MediaPlayer
import androidx.annotation.RequiresApi
import android.content.Intent
import android.media.AudioAttributes
import android.media.MediaPlayer
import android.media.MediaPlayer.OnPreparedListener
import android.net.Uri
import android.os.*
import android.util.Log
import androidx.annotation.RequiresApi
class AlarmService : Service(), OnPreparedListener {
var mediaPlayer: MediaPlayer? = null
private var mediaPlayer: MediaPlayer? = null
private var vibrator: Vibrator? = null
@SuppressLint("Recycle")
@RequiresApi(api = Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
if (intent.action == "stop") {
onDestroy()
return START_STICKY
}
val sound = intent.extras?.getString("sound")
val noSound = intent.extras?.getBoolean("noSound") == true
val db = DatabaseHelper(applicationContext).readableDatabase
val sound = db.rawQuery("SELECT sound FROM settings", null)
.let {
it.moveToFirst()
it.getString(0)
}
Log.d("AlarmService", "sound=$sound")
val noSound = db.rawQuery("SELECT noSound FROM settings", null)
.let {
it.moveToFirst()
it.getInt(0) == 1
}
Log.d("AlarmService", "noSound=$noSound")
if (sound == null && !noSound) {
mediaPlayer = MediaPlayer.create(applicationContext, R.raw.argon)
@ -42,6 +59,13 @@ class AlarmService : Service(), OnPreparedListener {
}
}
val vibrate = db.rawQuery("SELECT vibrate FROM settings", null)
.let {
it.moveToFirst()
it.getInt(0) == 1
}
if (!vibrate) return START_STICKY
val pattern = longArrayOf(0, 300, 1300, 300, 1300, 300)
vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val vibratorManager =
@ -55,9 +79,7 @@ class AlarmService : Service(), OnPreparedListener {
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
val vibrate = intent.extras!!.getBoolean("vibrate")
if (vibrate)
vibrator!!.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes)
vibrator!!.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes)
return START_STICKY
}

View File

@ -0,0 +1,22 @@
package com.massive
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
class DatabaseHelper(context: Context) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
companion object {
private const val DATABASE_NAME = "massive.db"
private const val DATABASE_VERSION = 1
}
override fun onCreate(db: SQLiteDatabase) {
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
}
override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
}
}