Skip to content

Commit

Permalink
Merge pull request #565 from AryanSarafDev/TimerRevamp
Browse files Browse the repository at this point in the history
Timer revamp
  • Loading branch information
AryanSarafDev authored May 30, 2024
2 parents da82d56 + 76a6349 commit 60b621d
Show file tree
Hide file tree
Showing 22 changed files with 2,816 additions and 847 deletions.
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

0 comments on commit 60b621d

Please sign in to comment.