Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timer revamp #565

Merged
merged 5 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
Expand Down Expand Up @@ -37,6 +38,12 @@
</intent-filter>
</receiver>

<receiver
android:name=".TimerNotification"
android:enabled="true"
android:exported="false">
</receiver>


<receiver
android:name=".AlarmReceiver"
Expand All @@ -50,6 +57,8 @@
android:exported="false">

</receiver>


<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,57 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.SystemClock
import java.time.LocalTime
import java.time.Duration
import org.json.JSONArray
import java.util.*

import android.app.NotificationChannel
import android.app.NotificationManager
import android.os.Build
import android.os.CountDownTimer
import androidx.core.app.NotificationCompat


class BootReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
// Open the database
if (intent.action == Intent.ACTION_BOOT_COMPLETED){

val dbHelper = DatabaseHelper(context)
val db = dbHelper.readableDatabase

// Get the latest alarm
val ringTime = getLatestAlarm(db, true)

// Close the database
db.close()

// Schedule the alarm
if (ringTime != null) {
scheduleAlarm(ringTime, context)
}

scheduleAlarm(ringTime, context)
val timerdbhelper = TimerDatabaseHelper(context)
val timerdb = timerdbhelper.readableDatabase
val time = getLatestTimer(timerdb)
timerdb.close()
var notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val commonTimer = CommonTimerManager.getCommonTimer(object : TimerListener {
override fun onTick(millisUntilFinished: Long) {
println(millisUntilFinished)
showTimerNotification(millisUntilFinished,"Timer",context)

}

}
override fun onFinish() {
notificationManager.cancel(1)
}
})


createNotificationChannel(context)



if (time!=null){

// Start or stop the timer based on your requirements
commonTimer.startTimer(time.second)

}


}}
fun scheduleAlarm(milliSeconds: Long, context: Context) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, AlarmReceiver::class.java)
Expand All @@ -47,6 +71,52 @@ class BootReceiver : BroadcastReceiver() {
val triggerTime = SystemClock.elapsedRealtime() + milliSeconds
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, pendingIntent)
}
private fun createNotificationChannel(context: Context) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
TimerService.TIMER_CHANNEL_ID,
"Timer Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}


private fun showTimerNotification(milliseconds: Long,timerName:String,context: Context){
var notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val deleteIntent = Intent(context,TimerNotification::class.java)
deleteIntent.action = "com.example.ultimate_alarm_clock.STOP_TIMERNOTIF"
val deletePendingIntent = PendingIntent.getBroadcast(context, 5, deleteIntent,
PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationCompat.Builder(context, TimerService.TIMER_CHANNEL_ID)
.setSmallIcon(R.mipmap.launcher_icon)
.setContentText("$timerName")
.setContentText(formatDuration(milliseconds))
.setOnlyAlertOnce(true)
.setDeleteIntent(deletePendingIntent)
.
build()
notificationManager.notify(1,notification)
}

private fun formatDuration(milliseconds: Long): String {
val seconds = (milliseconds / 1000) % 60
val minutes = (milliseconds / (1000 * 60)) % 60
val hours = (milliseconds / (1000 * 60 * 60)) % 24

return if (hours > 0) {
String.format("%02d:%02d:%02d", hours, minutes, seconds)
} else {
String.format("%02d:%02d", minutes, seconds)
}
}






Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.example.ultimate_alarm_clock

import android.os.CountDownTimer

object CommonTimerManager {
private var commonTimer: CommonTimer? = null

fun getCommonTimer(listener: TimerListener): CommonTimer {
if (commonTimer == null) {
commonTimer = CommonTimer(listener)
}
return commonTimer!!
}
}
class CommonTimer(private val listener: TimerListener) {
private var timer: CountDownTimer? = null

fun startTimer(durationMillis: Long) {
timer?.cancel() // Cancel any existing timer
timer = object : CountDownTimer(durationMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
listener.onTick(millisUntilFinished)
}

override fun onFinish() {
listener.onFinish()
}
}.start()
}

fun stopTimer() {
timer?.cancel()
}
}

interface TimerListener {
fun onTick(millisUntilFinished: Long)
fun onFinish()
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,7 @@ fun getLatestAlarm(db: SQLiteDatabase, wantNextAlarm: Boolean): Long? {
}
}

fun calculatePriority(days: String, currentDay: Int): Int {
if (days == "0000000") {
return 0
}
for (i in 1..7) {
val dayIndex = (currentDay + i) % 7
if (days[dayIndex] == '1') {
return i
}
}
return 7
}


fun stringToTimeOfDay(time: String): LocalTime {
val parts = time.split(":")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
package com.example.ultimate_alarm_clock

import android.os.Bundle
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.android.FlutterActivityLaunchConfigs
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugin.common.MethodChannel
import android.app.ActivityManager
import android.app.AlarmManager
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.SystemClock
import android.app.ActivityManager
import android.widget.Toast
import android.os.PowerManager
import android.util.Log
import android.view.WindowManager
import android.content.IntentFilter
import android.media.Ringtone
import android.media.RingtoneManager
import android.net.Uri
import java.time.LocalTime
import android.os.Bundle
import android.os.SystemClock
import android.view.WindowManager
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel


class MainActivity : FlutterActivity() {
class MainActivity : FlutterActivity() {

companion object {
const val CHANNEL1 = "ulticlock"
Expand All @@ -37,6 +32,17 @@ class MainActivity : FlutterActivity() {
private var ringtone: Ringtone? = null
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var intentFilter = IntentFilter()
intentFilter.addAction("com.example.ultimate_alarm_clock.START_TIMERNOTIF")
intentFilter.addAction("com.example.ultimate_alarm_clock.STOP_TIMERNOTIF")
context.registerReceiver(TimerNotification(),intentFilter)
}





override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
Expand Down Expand Up @@ -85,7 +91,18 @@ class MainActivity : FlutterActivity() {
} else if (call.method == "stopDefaultAlarm") {
stopDefaultAlarm()
result.success(null)
} else
} else if(call.method == "runtimerNotif")
{
val startTimerIntent = Intent("com.example.ultimate_alarm_clock.START_TIMERNOTIF")
context.sendBroadcast(startTimerIntent)

}else if(call.method == "clearTimerNotif"){
val stopTimerIntent = Intent("com.example.ultimate_alarm_clock.STOP_TIMERNOTIF")
context.sendBroadcast(stopTimerIntent)
var notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancel(1)
}
else
{
result.notImplemented()
}
Expand Down Expand Up @@ -118,6 +135,11 @@ class MainActivity : FlutterActivity() {
}
}






fun bringAppToForeground(context: Context) {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
val appTasks = activityManager?.appTasks
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.ultimate_alarm_clock.TimerBroadcasts

import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.ultimate_alarm_clock.CommonTimerManager
import com.example.ultimate_alarm_clock.TimerListener

class CancelTimer : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
var notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val commonTimer = CommonTimerManager.getCommonTimer(object : TimerListener {
override fun onTick(millisUntilFinished: Long) {
}
override fun onFinish() {
notificationManager.cancel(1)
}
})
commonTimer.stopTimer()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.ultimate_alarm_clock
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class TimerDatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

companion object {
private const val DATABASE_VERSION = 1
private const val DATABASE_NAME = "timer.db"
}

override fun onCreate(db: SQLiteDatabase) {
db.rawQuery(""" create table timers (
id integer primary key autoincrement,
startedOn text not null,
timerValue integer not null,
timeElapsed integer not null,
ringtoneName text not null,
timerName text not null,
isPaused integer not null)""",null)
}

override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
}
}
Loading