fmassive/android/app/src/main/kotlin/com/example/fmassive/MainActivity.kt

196 lines
7.8 KiB
Kotlin

package com.example.fmassive
import android.annotation.SuppressLint
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.content.IntentFilter
import android.os.Build
import android.os.CountDownTimer
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import kotlin.math.floor
class MainActivity : FlutterActivity() {
private val CHANNEL = "com.massive/android"
@RequiresApi(Build.VERSION_CODES.O)
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
// This method is invoked on the main thread.
call, result ->
if (call.method == "timer") {
val args = call.arguments as ArrayList<Long>
timer(args[0])
} else {
result.notImplemented()
}
}
}
private var countdownTimer: CountDownTimer? = null
var currentMs: Long = 0
private var running = false
private val stopReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context?, intent: Intent?) {
Log.d("AlarmModule", "Received stop broadcast intent")
stop()
}
}
private val addReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context?, intent: Intent?) {
add()
}
}
init {
}
@RequiresApi(api = Build.VERSION_CODES.O)
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.toLong())
countdownTimer?.start()
running = true
//val manager = getManager()
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
//val intent = Intent(context, AlarmService::class.java)
//context.stopService(intent)
}
@RequiresApi(api = Build.VERSION_CODES.O)
fun stop() {
Log.d("AlarmModule", "Stop alarm.")
countdownTimer?.cancel()
running = false
//val intent = Intent(context, AlarmService::class.java)
//reactApplicationContext?.stopService(intent)
//val manager = getManager()
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
//manager.cancel(NOTIFICATION_ID_PENDING)
//val params = Arguments.createMap().apply {
// putString("minutes", "00")
// putString("seconds", "00")
//}
//reactApplicationContext
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
// .emit("tick", params)
}
@RequiresApi(api = Build.VERSION_CODES.O)
fun timer(milliseconds: Long) {
context.registerReceiver(stopReceiver, IntentFilter(STOP_BROADCAST))
context.registerReceiver(addReceiver, IntentFilter(ADD_BROADCAST))
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
//val manager = getManager()
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
//val intent = Intent(reactApplicationContext, AlarmService::class.java)
//reactApplicationContext.stopService(intent)
countdownTimer?.cancel()
countdownTimer = getTimer(milliseconds)
countdownTimer?.start()
running = true
}
@RequiresApi(Build.VERSION_CODES.M)
private fun getTimer(
endMs: Long,
): CountDownTimer {
val builder = getBuilder()
return object : CountDownTimer(endMs.toLong(), 1000) {
@RequiresApi(Build.VERSION_CODES.O)
override fun onTick(current: Long) {
currentMs = current
val seconds =
floor((current / 1000).toDouble() % 60).toInt().toString().padStart(2, '0')
val minutes =
floor((current / 1000).toDouble() / 60).toInt().toString().padStart(2, '0')
builder.setContentText("$minutes:$seconds").setAutoCancel(false).setDefaults(0)
.setProgress(endMs.toInt(), current.toInt(), false)
.setCategory(NotificationCompat.CATEGORY_PROGRESS).priority =
NotificationCompat.PRIORITY_LOW
val manager = getManager()
Log.d("AlarmModule", "Notify $NOTIFICATION_ID_PENDING")
manager.notify(NOTIFICATION_ID_PENDING, builder.build())
//val params = Arguments.createMap().apply {
// putString("minutes", minutes)
// putString("seconds", seconds)
//}
//reactApplicationContext
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
// .emit("tick", params)
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onFinish() {
//val context = reactApplicationContext
//context.startForegroundService(Intent(context, AlarmService::class.java))
//context
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
// .emit("finish", Arguments.createMap().apply {
// putString("minutes", "00")
// putString("seconds", "00")
// })
}
}
}
@SuppressLint("UnspecifiedImmutableFlag")
@RequiresApi(Build.VERSION_CODES.M)
private fun getBuilder(): NotificationCompat.Builder {
val contentIntent = Intent(context, MainActivity::class.java)
val pendingContent =
PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
val addBroadcast = Intent(ADD_BROADCAST).apply {
setPackage(context.packageName)
}
val pendingAdd =
PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE)
val stopBroadcast = Intent(STOP_BROADCAST)
stopBroadcast.setPackage(context.packageName)
val pendingStop =
PendingIntent.getBroadcast(context, 0, stopBroadcast, PendingIntent.FLAG_IMMUTABLE)
return NotificationCompat.Builder(context, CHANNEL_ID_PENDING)
.setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24).setContentTitle("Resting")
.setContentIntent(pendingContent)
.addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop)
.addAction(R.drawable.ic_baseline_stop_24, "Add 1 min", pendingAdd)
.setDeleteIntent(pendingStop)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun getManager(): NotificationManager {
val notificationManager = context.getSystemService(
NotificationManager::class.java
)
val timersChannel = NotificationChannel(
CHANNEL_ID_PENDING, CHANNEL_ID_PENDING, NotificationManager.IMPORTANCE_LOW
)
timersChannel.setSound(null, null)
timersChannel.description = "Progress on rest timers."
notificationManager.createNotificationChannel(timersChannel)
return notificationManager
}
companion object {
const val STOP_BROADCAST = "stop-timer-event"
const val ADD_BROADCAST = "add-timer-event"
const val CHANNEL_ID_PENDING = "Timer"
const val NOTIFICATION_ID_PENDING = 1
}
}