Skip to content

Comments

Broadcast intents#156

Open
keithvassallomt wants to merge 4 commits intotimer-machine:developfrom
keithvassallomt:broadcast-intents
Open

Broadcast intents#156
keithvassallomt wants to merge 4 commits intotimer-machine:developfrom
keithvassallomt:broadcast-intents

Conversation

@keithvassallomt
Copy link

Summary

Adds a public broadcast intent API that allows external apps to control timers. The primary use case is voice assistant integration — for example, telling a voice assistant to set a timer, which sends a broadcast intent to create and start one. I intend to add a PR to the Dicio repo with a skill allowing it to talk to TimeR Machine via this intent system.

New module: app-broadcast

A new app-broadcast module with an exported BroadcastReceiver listening on:

io.github.deweyreed.timer.BROADCAST_TIMER_CONTROL

Supported commands

Command Extras Description
create name (String), duration_seconds (long) Creates a new countdown timer and starts it immediately. The timer includes a notifier step with music, vibration, screen, and halt behaviours.
start timer_id (int) or timer_name (String) Starts an existing timer by ID or name (case-insensitive).
pause timer_id (int) or timer_name (String) Pauses a running timer.
resume timer_id (int) or timer_name (String) Resumes a paused timer.
reset timer_id (int) or timer_name (String) Resets/stops a timer.
dismiss timer_id (int) or timer_name (String), optional Dismisses a specific timer, or all running timers if no ID/name is provided.
list (none) Broadcasts a response intent (io.github.deweyreed.timer.BROADCAST_TIMER_LIST) with arrays of running timer IDs, names, and remaining time.

Timers can be targeted by either timer_id or timer_name. Name lookup is case-insensitive and returns the first match.

Architecture

  • TimerBroadcastReceiver — Exported receiver, handles intent routing. Uses ContextCompat.startForegroundService to send commands to MachineService, consistent with the existing Tasker integration approach.
  • BroadcastPresenter — Resolves timer IDs/names and maps commands to service intents. Injected via Hilt.
  • TimerFactory — Creates TimerEntity instances for the create command, with a countdown step and a notifier step.
  • FindTimerInfoByName — New use case for case-insensitive timer lookup by name, backed by a new DAO query.

Limitations

Same as the Tasker integration: on Android 12+, startForegroundService from a broadcast receiver requires battery optimization to be disabled for the app. The existing whitelist guideline already covers this.

Other changes

  • StreamMachineIntentProvider.stopAllIntent() — New method to support the dismiss command (dismiss all timers).
  • Full-screen intent permission setting (Android 14+) — Adds a settings entry under Notifications that takes the user to the system full-screen intent permission page. This entry only appears when the permission is not granted and auto-hides once it is. On Android 14+, this permission is no longer granted by default, and there is no natural in-flow moment to request it — users would only discover it's missing when a timer fires without the full-screen overlay.

keithvassallomt and others added 4 commits February 18, 2026 12:21
Allows external apps (e.g. voice assistants) to create, start, pause,
resume, reset, and dismiss timers via broadcast intents. Includes
handling for ForegroundServiceStartNotAllowedException on Android 12+.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sends a response broadcast with timer IDs and names of all currently
running timers, identified via active notifications.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extracts the formatted remaining time (e.g. "04:58") from each
timer's notification and includes it in the response broadcast
as the timer_remaining string array.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows a settings entry under Notifications that takes the user to the
system full-screen intent permission page. Auto-hides once permission
is granted. This is needed because the permission is not granted by
default on Android 14+ and there is no natural in-flow moment to
request it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant