Skip to content

Commit

Permalink
Add tile to change timeout
Browse files Browse the repository at this point in the history
Closes #206
  • Loading branch information
mueller-ma committed Mar 6, 2023
1 parent 66284d3 commit 9cdca05
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 93 deletions.
21 changes: 19 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,26 @@
</receiver>

<service
android:name=".CoffeeTile"
android:name=".tiles.ToggleTile"
android:icon="@drawable/ic_twotone_free_breakfast_24"
android:label="@string/app_name"
android:label="@string/toggle_coffee"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:exported="true">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
<meta-data
android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
<meta-data
android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>

<service
android:name=".tiles.TimeoutTile"
android:icon="@drawable/ic_twotone_free_breakfast_24"
android:label="@string/timeout_next"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:exported="true">
<intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import com.github.muellerma.coffee.tiles.ToggleTile

class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Expand All @@ -12,7 +13,7 @@ class BootReceiver : BroadcastReceiver() {
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
CoffeeTile.requestTileStateUpdate(context)
ToggleTile.requestTileStateUpdate(context)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.github.muellerma.coffee
import android.app.Application
import android.os.Build
import androidx.preference.PreferenceManager
import com.github.muellerma.coffee.tiles.TimeoutTile
import com.github.muellerma.coffee.tiles.ToggleTile
import com.google.android.material.color.DynamicColors

class CoffeeApplication : Application() {
Expand All @@ -16,7 +18,8 @@ class CoffeeApplication : Application() {
PreferenceManager.setDefaultValues(this, R.xml.pref_main, false)
DynamicColors.applyToActivitiesIfAvailable(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
observers.add(CoffeeTile.TileServiceStatusObserver(this))
observers.add(ToggleTile.TileServiceStatusObserver(this))
observers.add(TimeoutTile.TileServiceStatusObserver(this))
}
}

Expand Down
72 changes: 0 additions & 72 deletions app/src/main/java/com/github/muellerma/coffee/CoffeeTile.kt

This file was deleted.

24 changes: 8 additions & 16 deletions app/src/main/java/com/github/muellerma/coffee/ForegroundService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ForegroundService : Service(), ServiceStatusObserver {

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand()")
val prefs = Prefs(applicationContext)
when (intent?.action) {
ACTION_STOP -> {
Log.d(TAG, "Received stop action")
Expand All @@ -31,13 +32,11 @@ class ForegroundService : Service(), ServiceStatusObserver {
}
ACTION_CHANGE_PREF_TIMEOUT -> {
Log.d(TAG, "Change timeout")
Prefs(applicationContext).timeout =
intent.getStringExtra(EXTRA_CHANGE_PREF_VALUE)?.toIntOrNull() ?: 0
prefs.timeout = prefs.nextTimeout
}
ACTION_CHANGE_PREF_ALLOW_DIMMING -> {
Log.d(TAG, "Change allow dimming")
Prefs(applicationContext).allowDimming =
intent.getBooleanExtra(EXTRA_CHANGE_PREF_VALUE, false)
prefs.allowDimming = !prefs.allowDimming
}
}

Expand Down Expand Up @@ -177,23 +176,16 @@ class ForegroundService : Service(), ServiceStatusObserver {
return getBaseNotification(title)
.setContentText(getString(R.string.tap_to_turn_off))
.setContentIntent(getPendingIntentForService(stopIntent, PendingIntent_Immutable, 0))
.addAction(getTimeoutAction(prefs))
.addAction(getTimeoutAction())
.addAction(getDimmingAction(prefs))
.setPublicVersion(getBaseNotification(title).build())
.build()
}

private fun getTimeoutAction(prefs: Prefs): NotificationCompat.Action {
private fun getTimeoutAction(): NotificationCompat.Action {
Log.d(TAG, "getTimeoutAction()")
val intent = Intent(this, ForegroundService::class.java).apply {
action = ACTION_CHANGE_PREF_TIMEOUT

val allTimeouts = applicationContext.resources.getStringArray(R.array.timeout_values)
val currentIndex = allTimeouts.indexOf(prefs.timeout.toString())
val nextIndex = (currentIndex + 1).mod(allTimeouts.size)
val nextTimeout = allTimeouts[nextIndex]

putExtra(EXTRA_CHANGE_PREF_VALUE, nextTimeout)
}
return NotificationCompat.Action(
R.drawable.ic_baseline_access_time_24,
Expand All @@ -205,7 +197,6 @@ class ForegroundService : Service(), ServiceStatusObserver {
private fun getDimmingAction(prefs: Prefs): NotificationCompat.Action {
val intent = Intent(this, ForegroundService::class.java).apply {
action = ACTION_CHANGE_PREF_ALLOW_DIMMING
putExtra(EXTRA_CHANGE_PREF_VALUE, !prefs.allowDimming)
}
val title = if (prefs.allowDimming) R.string.allow_dimming_disable else R.string.allow_dimming_enable
return NotificationCompat.Action(
Expand Down Expand Up @@ -278,9 +269,8 @@ class ForegroundService : Service(), ServiceStatusObserver {
companion object {
private val TAG = ForegroundService::class.java.simpleName
private const val ACTION_STOP = "stop_action"
private const val ACTION_CHANGE_PREF_TIMEOUT = "change_pref_timeout"
const val ACTION_CHANGE_PREF_TIMEOUT = "change_pref_timeout"
private const val ACTION_CHANGE_PREF_ALLOW_DIMMING = "change_pref_dimming"
private const val EXTRA_CHANGE_PREF_VALUE = "change_pref_value"
const val NOTIFICATION_ID = 1
const val NOTIFICATION_CHANNEL_ID = "foreground_service"

Expand Down Expand Up @@ -313,5 +303,7 @@ class ForegroundService : Service(), ServiceStatusObserver {
STOP,
TOGGLE
}


}
}
16 changes: 15 additions & 1 deletion app/src/main/java/com/github/muellerma/coffee/Prefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,28 @@ import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.preference.PreferenceManager

class Prefs(context: Context) {
class Prefs(private val context: Context) {
var sharedPrefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private set

var timeout: Int
get() = sharedPrefs.getString("timeout", "0")?.toInt() ?: 0
set(value) = sharedPrefs.edit { putString("timeout", value.toString()) }

val nextTimeout: Int
get() {
val allTimeouts = context.resources.getStringArray(R.array.timeout_values)
val currentIndex = allTimeouts.indexOf(timeout.toString())
val nextIndex = (currentIndex + 1).mod(allTimeouts.size)
return allTimeouts[nextIndex].toIntOrNull() ?: 0
}

val firstTimeout: Int
get() {
val allTimeouts = context.resources.getStringArray(R.array.timeout_values)
return allTimeouts[1].toIntOrNull() ?: 0
}

var allowDimming: Boolean
get() = sharedPrefs.getBoolean("allow_dimming", false)
set(value) = sharedPrefs.edit { putBoolean("allow_dimming", value) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.github.muellerma.coffee.tiles

import android.os.Build
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import android.util.Log
import androidx.annotation.RequiresApi
import com.github.muellerma.coffee.R
import com.github.muellerma.coffee.ServiceStatus
import com.github.muellerma.coffee.coffeeApp
import com.github.muellerma.coffee.toFormattedTime

@RequiresApi(Build.VERSION_CODES.N)
abstract class AbstractTile : TileService() {
override fun onStartListening() {
Log.d(TAG, "onStartListening()")
setTileState()
super.onStartListening()
}

override fun onTileAdded() {
Log.d(TAG, "onTileAdded()")
setTileState()
super.onTileAdded()
}

private fun setTileState() {
val currentStatus = coffeeApp().lastStatusUpdate
Log.d(TAG, "setTileState(): running = $currentStatus")
val tile = qsTile ?: return

val (tileState, tileSubtitle) = when (currentStatus) {
is ServiceStatus.Stopped -> Pair(Tile.STATE_INACTIVE, "")
is ServiceStatus.Running -> {
if (currentStatus.remainingSeconds == null) {
Pair(Tile.STATE_ACTIVE, "")
} else {
Pair(Tile.STATE_ACTIVE, currentStatus.remainingSeconds.toFormattedTime())
}
}
}

tile.apply {
state = tileState
label = getString(R.string.app_name)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
subtitle = tileSubtitle
}
updateTile()
}
}

companion object {
private val TAG = AbstractTile::class.java.simpleName
}
}
46 changes: 46 additions & 0 deletions app/src/main/java/com/github/muellerma/coffee/tiles/TimeoutTile.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.github.muellerma.coffee.tiles

import android.content.ComponentName
import android.content.Context
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.github.muellerma.coffee.*

@RequiresApi(Build.VERSION_CODES.N)
class TimeoutTile : AbstractTile() {
override fun onClick() {
Log.d(TAG, "onClick()")
val prefs = Prefs(applicationContext)
when {
coffeeApp().lastStatusUpdate is ServiceStatus.Stopped -> {
prefs.timeout = prefs.firstTimeout
ForegroundService.changeState(this, ForegroundService.Companion.STATE.START, false)
}
prefs.nextTimeout == 0 -> {
prefs.timeout = 0
ForegroundService.changeState(this, ForegroundService.Companion.STATE.STOP, false)
}
else -> {
prefs.timeout = prefs.nextTimeout
}

}
}

@RequiresApi(Build.VERSION_CODES.N)
companion object {
private val TAG = TimeoutTile::class.java.simpleName

fun requestTileStateUpdate(context: Context) {
Log.d(TAG, "requestTileStateUpdate()")
requestListeningState(context, ComponentName(context, TimeoutTile::class.java))
}
}

class TileServiceStatusObserver(private val context: Context) : ServiceStatusObserver {
override fun onServiceStatusUpdate(status: ServiceStatus) {
requestTileStateUpdate(context)
}
}
}
33 changes: 33 additions & 0 deletions app/src/main/java/com/github/muellerma/coffee/tiles/ToggleTile.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.muellerma.coffee.tiles

import android.content.ComponentName
import android.content.Context
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.github.muellerma.coffee.*

@RequiresApi(Build.VERSION_CODES.N)
class ToggleTile : AbstractTile() {
override fun onClick() {
Log.d(TAG, "onClick()")
ForegroundService.changeState(this, ForegroundService.Companion.STATE.TOGGLE, false)
}

@RequiresApi(Build.VERSION_CODES.N)
companion object {
private val TAG = ToggleTile::class.java.simpleName

fun requestTileStateUpdate(context: Context) {
Log.d(TAG, "requestTileStateUpdate()")
requestListeningState(context, ComponentName(context, ToggleTile::class.java))
}
}

class TileServiceStatusObserver(private val context: Context) : ServiceStatusObserver {
override fun onServiceStatusUpdate(status: ServiceStatus) {
requestTileStateUpdate(context)
}

}
}

0 comments on commit 9cdca05

Please sign in to comment.