Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tauri-plugin-timer

An ongoing timer notification for Android, driven from a Tauri app. The notification carries the system chronometer and pause / resume / stop buttons, and it keeps counting with no JavaScript running and the app in the background.

Written for freel, a freelance time tracker, and kept as a separate crate because nothing in it is specific to that app. Android only — on desktop every call is a no-op, so the host app does not need cfg branches.

Why a plugin at all

A timer in a web view stops being a timer the moment Android reclaims the process. Three separate things had to be true for it to survive:

  1. The elapsed time is Android's to count. The plugin hands the notification a baseMs instant, and NotificationCompat.setUsesChronometer counts up from it. Nothing has to tick on the JS side — a backgrounded web view can be frozen and the number on screen stays right.
  2. The process has to stay alive. The notification is held by a foreground service. Without it the process is reclaimed, and the notification's buttons go dead along with the broadcast receiver and the plugin instance behind them. START_STICKY brings the service back if the system reclaims it anyway.
  3. The buttons have to reach the app. Taps land in a BroadcastReceiver, which forwards them to the plugin, which relays them to the web layer as an event. The web layer can then act on a button pressed while the app was nowhere on screen.

API

use tauri_plugin_timer::TimerExt;

app.timer().show(ShowArgs {
    title: "Landing page".into(),
    base_ms: started_at_epoch_millis,
    paused: false,
    paused_label: "Paused".into(),
    running_label: "Running".into(),
    pause_action_label: "Pause".into(),
    resume_action_label: "Resume".into(),
    stop_action_label: "Stop".into(),
    channel_name: "Task timer".into(),
})?;

app.timer().cancel()?;

All labels are passed in rather than baked into the plugin: the host app owns its wording and its translations.

From the web layer:

import { addPluginListener, invoke } from '@tauri-apps/api/core';

await invoke('plugin:timer|show', {
  args: { title, baseMs, paused, pausedLabel, runningLabel, /* … */ },
});

// Button taps arrive as an event, including ones pressed while the app
// was nowhere on screen.
const listener = await addPluginListener<{ action: string }>(
  'timer',
  'timer-action',
  ({ action }) => {
    // 'pause' | 'resume' | 'stop'
  },
);

await invoke('plugin:timer|cancel');
listener.unregister();

baseMs is the instant the chronometer counts from, so banked time from earlier pauses is folded into it by the caller — the notification then shows total session time rather than time since the last resume.

Permissions

The default permission set allows all four commands:

permissions = [
  "allow-show",
  "allow-cancel",
  "allow-registerListener",
  "allow-removeListener",
]

Add timer:default to the app's capabilities, or pick the individual permissions.

Android manifest

Merged into the host app automatically:

Permission Why
POST_NOTIFICATIONS Android 13+ requires it before anything is shown
FOREGROUND_SERVICE The service that holds the notification
FOREGROUND_SERVICE_SPECIAL_USE Declared subtype: an ongoing work timer that must keep counting in the background

The service and the receiver are both exported="false" — nothing outside the app can start them.

Install

[dependencies]
tauri-plugin-timer = "0.1"
tauri::Builder::default()
    .plugin(tauri_plugin_timer::init())

Structure

src/lib.rs                        plugin entry, ShowArgs, desktop no-op
android/src/main/
  java/com/freel/timer/
    TimerPlugin.kt                @TauriPlugin commands + action receiver
    TimerService.kt               foreground service holding the notification
  AndroidManifest.xml             permissions, service, receiver
  res/drawable/ic_timer_small.xml status bar icon
permissions/                      whitelist for Tauri's capability system

License

MIT

About

Android ongoing timer notification for Tauri — system chronometer and action buttons held by a foreground service, so it keeps counting with no JavaScript running

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages