Conversation
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+.
Sends a response broadcast with timer IDs and names of all currently running timers, identified via active notifications.
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.
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.
28f82af to
dfa66f2
Compare
|
Any feedback on this? I'll gladly make any changes you need to ensure the best UI/UX and that everything is in-line with how you like the code to be in TimeR Machine! |
|
Hello! My main job has been quite busy recently, and it will get harsher in the following months. :D Thank you for the PR. It didn't consider the hostile background running environment on Android. Broadcasts on modern Android don't work reliably. Complicated features like this require more consideration of security and edge cases as well. If your goal is to support voice assistants, there must be system services or existing APIs to achieve it without having to implement a complete broadcasting system. |
|
Hi, thanks for the feedback and no rush at all — I understand busy schedules! You raise fair points. Let me address them: Background execution: The implementation already handles Android 12+ foreground service restrictions — it catches Security: The receiver is currently exported without permission protection. I can add a custom signature-level permission or a Regarding existing APIs: As far as I know, Android doesn't offer a standard system API for third-party timer apps to expose their functionality to voice assistants or automation tools. Google Assistant integration requires specific partnerships. Broadcast intents are the established pattern for how automation tools like Tasker communicate with third-party apps — and I noticed the project already has some awareness of Tasker-style integration. This approach follows that same convention. To reduce risk, I'm happy to:
Let me know what you think, and whether any of these changes would make you more comfortable with the PR. Happy to iterate on it. |
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-broadcastA new
app-broadcastmodule with an exportedBroadcastReceiverlistening on:Supported commands
createname(String),duration_seconds(long)starttimer_id(int) ortimer_name(String)pausetimer_id(int) ortimer_name(String)resumetimer_id(int) ortimer_name(String)resettimer_id(int) ortimer_name(String)dismisstimer_id(int) ortimer_name(String), optionallistio.github.deweyreed.timer.BROADCAST_TIMER_LIST) with arrays of running timer IDs, names, and remaining time.Timers can be targeted by either
timer_idortimer_name. Name lookup is case-insensitive and returns the first match.Architecture
TimerBroadcastReceiver— Exported receiver, handles intent routing. UsesContextCompat.startForegroundServiceto send commands toMachineService, consistent with the existing Tasker integration approach.BroadcastPresenter— Resolves timer IDs/names and maps commands to service intents. Injected via Hilt.TimerFactory— CreatesTimerEntityinstances for thecreatecommand, 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+,
startForegroundServicefrom 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 thedismisscommand (dismiss all timers).