<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Android | Antoine Weill--Duflos</title>
    <link>https://antoine.weill-duflos.fr/en/tag/android/</link>
      <atom:link href="https://antoine.weill-duflos.fr/en/tag/android/index.xml" rel="self" type="application/rss+xml" />
    <description>Android</description>
    <generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Sat, 13 Jun 2026 00:00:00 +0000</lastBuildDate>
    <image>
      <url>https://antoine.weill-duflos.fr/media/icon_hu_d686267daab28486.png</url>
      <title>Android</title>
      <link>https://antoine.weill-duflos.fr/en/tag/android/</link>
    </image>
    
    <item>
      <title>Pointeuse: a native Odoo time tracker for desktop and Android</title>
      <link>https://antoine.weill-duflos.fr/en/project/pointeuse/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://antoine.weill-duflos.fr/en/project/pointeuse/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/Leicas/pointeuse&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Pointeuse&lt;/a&gt; is a fast, native time tracker for &lt;a href=&#34;https://www.odoo.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Odoo&lt;/a&gt;. &lt;em&gt;Pointeuse&lt;/em&gt; is French for a punch clock, which is exactly what it is: a small app that lives in your system tray and lets you start and stop a timer against any Odoo task without opening a browser.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.odoo.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Odoo&lt;/a&gt; is a powerful ERP, but its full interface can be overwhelming for someone who just wants to record what they worked on. Pointeuse is the opposite: the simplest possible surface in front of it. Your whole job is to say which task you are on, get a gentle reminder, and switch with a click; the time funnels into Odoo as proper timesheets behind the scenes, so the company keeps all of the ERP&amp;rsquo;s power. It is also a demonstration that integrating with Odoo is easy, on the desktop or on mobile, with no server-side module.&lt;/p&gt;
&lt;p&gt;It does the things an Odoo timesheet workflow needs, but as a native app instead of a web tab:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Track time against Odoo tasks.&lt;/strong&gt; Start or stop a timer on any &lt;code&gt;project.task&lt;/code&gt;; the timesheets land in &lt;code&gt;account.analytic.line&lt;/code&gt; where Odoo expects them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attendance integration.&lt;/strong&gt; Check in and check out (&lt;code&gt;hr.attendance&lt;/code&gt;) from the app or the tray. The timer auto-stops when you check out from anywhere else, including the Odoo web client or mobile.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Idle reminders.&lt;/strong&gt; A configurable popup asks what you are working on, with quick-switch suggestions. On Android these become notifications with action buttons.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offline-first.&lt;/strong&gt; All Odoo data is cached in SQLite. Timesheets queue locally when you are offline and sync when the connection returns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A task dashboard.&lt;/strong&gt; A kanban board grouped by stage and project, a task detail panel, and a time log with day, week, and month views.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It talks to any Odoo 14+ instance over standard XML-RPC, with no server-side module to install. Credentials, or an API key for Odoo Online, are stored in the system keyring, never on disk.&lt;/p&gt;
&lt;p&gt;Under the hood it is built with &lt;strong&gt;Tauri 2&lt;/strong&gt; and a &lt;strong&gt;Rust&lt;/strong&gt; backend, with a deliberately &lt;strong&gt;zero-framework vanilla JS&lt;/strong&gt; frontend. One codebase ships for &lt;strong&gt;Windows, Linux, macOS, and Android&lt;/strong&gt;. Commits to &lt;code&gt;main&lt;/code&gt; follow Conventional Commits, semantic-release cuts the versions, GitHub Actions builds all four platforms, and the desktop apps self-update from GitHub Releases.&lt;/p&gt;
&lt;p&gt;Pointeuse is &lt;strong&gt;MIT licensed&lt;/strong&gt;. The full story of why I built it and how it works is in the blog post &lt;a href=&#34;../../post/pointeuse/&#34;&gt;Pointeuse: a native, offline-first Odoo time tracker&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pointeuse: a Native, Offline-First Time Tracker for Odoo</title>
      <link>https://antoine.weill-duflos.fr/en/post/pointeuse/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://antoine.weill-duflos.fr/en/post/pointeuse/</guid>
      <description>&lt;p&gt;















&lt;figure  id=&#34;figure-the-pointeuse-task-dashboard-kanban-grouped-by-stage-with-effort-bars-deadlines-and-one-click-timer-start-screens-use-a-throwaway-odoo-demo-with-sample-projects-so-there-is-no-real-data-here&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;The Pointeuse task dashboard: a kanban board with columns grouped by stage, task cards showing project, effort bars, and deadlines, with a play button on each card to start tracking&#34; srcset=&#34;
               /en/post/pointeuse/featured_hu_c78fb50d28b8ea95.webp 400w,
               /en/post/pointeuse/featured_hu_bf5c2a403149cd66.webp 760w,
               /en/post/pointeuse/featured_hu_eacfcd29b9ffc67a.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/pointeuse/featured_hu_c78fb50d28b8ea95.webp&#34;
               width=&#34;760&#34;
               height=&#34;505&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      The Pointeuse task dashboard, kanban grouped by stage, with effort bars, deadlines, and one-click timer start. Screens use a throwaway Odoo demo with sample projects, so there is no real data here.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.odoo.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Odoo&lt;/a&gt; is a genuinely powerful ERP. It runs sales, inventory, projects, HR, and accounting in one place, and the time you log into it feeds real business data. But that power has a cost at the edges. For an everyday user who just wants to record what they worked on, the full web interface is a lot: open a tab, wait for the client, find the right task, add a timesheet line, set the hours. Even inside a company that already lives in Odoo, that friction is real, and friction is exactly what makes people stop logging their time honestly.&lt;/p&gt;
&lt;p&gt;So I wanted the opposite: the simplest, nicest possible way to track time against Odoo. Something where your whole job is to &lt;strong&gt;say which task you are on&lt;/strong&gt;, get a gentle reminder now and then, and &lt;strong&gt;switch tasks with a click&lt;/strong&gt;. Everything else, the timesheet lines, the attendance records, the syncing, should happen for you, in the background, landing in Odoo as proper data. I built that, and called it &lt;strong&gt;Pointeuse&lt;/strong&gt;, French for a punch clock. It is open source under the MIT license.&lt;/p&gt;
&lt;p&gt;It is also a demonstration. Pointeuse shows you can integrate with Odoo &lt;strong&gt;really easily&lt;/strong&gt;, as a desktop app or on mobile, without installing anything server-side, and put a small, friendly surface in front of all the ERP power Odoo already has. You keep Odoo doing what it is great at, and your users only ever see a punch clock.&lt;/p&gt;
&lt;h2 id=&#34;what-it-does&#34;&gt;What it does&lt;/h2&gt;
&lt;p&gt;Pointeuse is a native app that lives in your &lt;strong&gt;system tray&lt;/strong&gt; and tracks time against your real Odoo tasks. The core loop is deliberately boring, which is the point:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Track time against Odoo tasks.&lt;/strong&gt; Start or stop a timer on any &lt;code&gt;project.task&lt;/code&gt;. The timesheet lands in &lt;code&gt;account.analytic.line&lt;/code&gt;, exactly where Odoo&amp;rsquo;s own timesheet views read from, so nothing about the rest of your Odoo setup has to change.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attendance integration.&lt;/strong&gt; You can check in and check out (&lt;code&gt;hr.attendance&lt;/code&gt;) from the app or straight from the tray. And because attendance is shared state, the timer &lt;strong&gt;auto-stops when you check out from anywhere else&lt;/strong&gt;, whether that is the Odoo web client or the mobile app. The desktop tracker and the rest of Odoo stay in agreement.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Idle reminders.&lt;/strong&gt; If you go quiet, a small popup asks what you are working on, with quick-switch suggestions so you can correct the record in one click. On Android the same nudge arrives as a notification with action buttons.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A task dashboard.&lt;/strong&gt; A kanban board grouped by stage and project, a task detail panel, and a time log with day, week, and month views, so the app is also where you look to see where your hours went.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;















&lt;figure  id=&#34;figure-connecting-to-an-odoo-instance-url-database-login-or-an-api-key-for-odoo-online-credentials-go-into-the-system-keyring-never-to-disk&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;The connect screen, a simple form for Odoo server URL, database, and login or API key&#34; srcset=&#34;
               /en/post/pointeuse/connect_hu_2dcc36bd6a75cb77.webp 400w,
               /en/post/pointeuse/connect_hu_f9bfe7771546dd3c.webp 760w,
               /en/post/pointeuse/connect_hu_4476e491fefee446.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/pointeuse/connect_hu_2dcc36bd6a75cb77.webp&#34;
               width=&#34;496&#34;
               height=&#34;689&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      Connecting to an Odoo instance. URL, database, login, or an API key for Odoo Online. Credentials go into the system keyring, never to disk.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;how-it-connects-xml-rpc-no-server-module&#34;&gt;How it connects: XML-RPC, no server module&lt;/h2&gt;
&lt;p&gt;The constraint I set myself was that Pointeuse must work against &lt;strong&gt;any&lt;/strong&gt; Odoo, including hosted Odoo Online instances and self-hosted ones, &lt;strong&gt;without installing a server-side module&lt;/strong&gt;. Asking people to deploy a custom Odoo addon just to track time would defeat the purpose.&lt;/p&gt;
&lt;p&gt;So it talks to Odoo over its standard &lt;strong&gt;XML-RPC&lt;/strong&gt; interface (&lt;code&gt;/xmlrpc/2/&lt;/code&gt;), which every Odoo 14 and later exposes out of the box. You give it three things: the server URL, the database name, and your login with either a password or an &lt;strong&gt;API key&lt;/strong&gt;. The API key path matters for Odoo Online, where the account password is blocked for external XML-RPC, so a key is the only way in. Whatever you give it is stored in the &lt;strong&gt;system keyring&lt;/strong&gt;, never written to disk.&lt;/p&gt;
&lt;p&gt;The nice property of building on the same XML-RPC models Odoo uses internally (&lt;code&gt;project.task&lt;/code&gt;, &lt;code&gt;account.analytic.line&lt;/code&gt;, &lt;code&gt;hr.attendance&lt;/code&gt;) is that there is no parallel source of truth. Pointeuse is just another, faster client for data Odoo already owns.&lt;/p&gt;
&lt;h2 id=&#34;offline-first-because-connections-drop&#34;&gt;Offline-first, because connections drop&lt;/h2&gt;
&lt;p&gt;The other thing I refused to compromise on was offline behaviour. A timer you cannot start because the WiFi blinked is useless, and a punch clock that loses a punch is worse than no punch clock at all.&lt;/p&gt;
&lt;p&gt;So everything is &lt;strong&gt;cached in SQLite&lt;/strong&gt; locally. Your projects, tasks, and recent timesheets are all available with no network round-trip, which is also why the app feels instant. When you record time while offline, the &lt;strong&gt;timesheet queues locally and syncs when the connection returns&lt;/strong&gt;. You are never blocked on the server being reachable at the exact moment you decide to start working.&lt;/p&gt;
&lt;p&gt;















&lt;figure  id=&#34;figure-the-timer-window-one-task-one-timer-todays-totals-at-a-glance-this-is-the-view-i-actually-keep-open&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;The timer window showing the active task and today&amp;rsquo;s tracked totals at a glance&#34; srcset=&#34;
               /en/post/pointeuse/timer_hu_be2c1fc8fec54efa.webp 400w,
               /en/post/pointeuse/timer_hu_a48d458bebaeecb4.webp 760w,
               /en/post/pointeuse/timer_hu_9a4491cf92ff9665.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/pointeuse/timer_hu_be2c1fc8fec54efa.webp&#34;
               width=&#34;496&#34;
               height=&#34;689&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      The timer window. One task, one timer, today&amp;rsquo;s totals at a glance. This is the view I actually keep open.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;how-it-is-built&#34;&gt;How it is built&lt;/h2&gt;
&lt;p&gt;Pointeuse is a &lt;a href=&#34;https://tauri.app/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tauri 2&lt;/a&gt; app. The backend is &lt;strong&gt;Rust&lt;/strong&gt;, and the frontend is &lt;strong&gt;vanilla JavaScript with no framework at all&lt;/strong&gt;. That zero-framework choice was deliberate: the UI is not complicated, and a punch clock has no business pulling in a megabyte of framework to render a few buttons and a list. The result is a small, fast binary rather than a browser-in-a-box.&lt;/p&gt;
&lt;p&gt;The Rust side does the real work: the XML-RPC client that speaks to Odoo, the SQLite cache (via &lt;code&gt;rusqlite&lt;/code&gt;, bundled so there is no system dependency), the timer engine, the attendance and reminder logic, and the system tray. HTTP goes through &lt;code&gt;reqwest&lt;/code&gt; on &lt;code&gt;rustls&lt;/code&gt;, XML through &lt;code&gt;quick-xml&lt;/code&gt;, and credentials through the &lt;code&gt;keyring&lt;/code&gt; crate. The same Rust core compiles for desktop and for Android, where the idle reminders become real Android notifications.&lt;/p&gt;
&lt;p&gt;One Tauri codebase produces installers for &lt;strong&gt;all four targets&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Windows&lt;/strong&gt;, a setup &lt;code&gt;.exe&lt;/code&gt; that auto-updates&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux&lt;/strong&gt;, an &lt;code&gt;.AppImage&lt;/code&gt; or &lt;code&gt;.deb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;macOS&lt;/strong&gt;, a universal &lt;code&gt;.dmg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android&lt;/strong&gt;, a sideloadable &lt;code&gt;.apk&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The release pipeline keeps that honest. Commits to &lt;code&gt;main&lt;/code&gt; follow &lt;a href=&#34;https://www.conventionalcommits.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Conventional Commits&lt;/a&gt;, &lt;a href=&#34;https://semantic-release.gitbook.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;semantic-release&lt;/a&gt; decides the version number from the commit history, GitHub Actions builds every platform, and the desktop apps &lt;strong&gt;self-update from GitHub Releases&lt;/strong&gt;. I push a commit, and a little while later a new version is on every machine without me touching an installer.&lt;/p&gt;
&lt;p&gt;















&lt;figure  id=&#34;figure-creating-a-task-without-leaving-the-app-you-can-create-it-and-start-tracking-it-in-the-same-step&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;The new-task modal: project picker, name, deadline, priority, and a Create and start option&#34; srcset=&#34;
               /en/post/pointeuse/new-task_hu_5e3d6f30b21a7aaf.webp 400w,
               /en/post/pointeuse/new-task_hu_4a9a813ba408164d.webp 760w,
               /en/post/pointeuse/new-task_hu_3e93d403768de754.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/pointeuse/new-task_hu_5e3d6f30b21a7aaf.webp&#34;
               width=&#34;760&#34;
               height=&#34;505&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      Creating a task without leaving the app. You can create it and start tracking it in the same step.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;why-the-data-matters-sred-and-grants&#34;&gt;Why the data matters: SR&amp;amp;ED and grants&lt;/h2&gt;
&lt;p&gt;There is a business reason to care about all this, beyond tidy reports. In Canada, the &lt;strong&gt;SR&amp;amp;ED&lt;/strong&gt; program (Scientific Research and Experimental Development) gives companies tax credits for eligible R&amp;amp;D work, and grant-funded projects come with their own reporting obligations. In both cases the claim rests on evidence: what was worked on, by whom, and for how long. If that record is thin, or reconstructed from memory after the fact, the claim is weaker and harder to defend.&lt;/p&gt;
&lt;p&gt;The catch is that this evidence is only ever as good as the daily habit that produces it. You cannot ask people to meticulously log every hour against the right project and also make logging painful. The friction wins, and the data quietly degrades. So the easiest possible time tracker is not a nicety, it is what makes the data trustworthy in the first place. Make the act of saying what you worked on take a single click, and over a year you end up with a record solid enough to stand behind a tax credit or a grant report.&lt;/p&gt;
&lt;p&gt;That is the rationale, really. It is all about people keeping tabs on their own time, and when it is easy enough, that works reasonably well.&lt;/p&gt;
&lt;h2 id=&#34;a-small-surface-over-a-powerful-erp&#34;&gt;A small surface over a powerful ERP&lt;/h2&gt;
&lt;p&gt;The point is not to replace anything Odoo does. The point is that the tool you reach for a hundred times a day should cost as close to zero attention as possible, so that the powerful ERP behind it actually gets fed accurate data. Odoo&amp;rsquo;s web timesheet is fine when you are already in Odoo doing something else. It is the wrong surface when all a person wants is to start the clock on a task and get back to work.&lt;/p&gt;
&lt;p&gt;That is the whole idea behind Pointeuse: keep the user&amp;rsquo;s job tiny, say what you are working on and switch with a click, and let everything funnel into Odoo as proper timesheets and attendance behind the scenes. The company keeps every report, every analytic, every bit of ERP power it already paid for. The user just sees a punch clock that opens instantly, survives a dropped connection, and stays in sync, whether they are at their desk or on their phone.&lt;/p&gt;
&lt;p&gt;And because the whole integration runs over Odoo&amp;rsquo;s standard XML-RPC with no server-side module, it doubles as a small proof that putting a friendly front end on Odoo is genuinely easy. It is the time tracker I wanted, and now I run my own days on it.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source and releases:&lt;/strong&gt; &lt;a href=&#34;https://github.com/Leicas/pointeuse&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Leicas/pointeuse&lt;/a&gt;, MIT licensed. Installers for Windows, Linux, macOS, and Android are on the &lt;a href=&#34;https://github.com/Leicas/pointeuse/releases&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Releases&lt;/a&gt; page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project page:&lt;/strong&gt; &lt;a href=&#34;../../project/pointeuse/&#34;&gt;Pointeuse&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It works against any Odoo 14 or later, with no server-side module to install. If your team runs on Odoo but logging time honestly is the part that keeps slipping, the answer is not more interface, it is less: a punch clock in front, the ERP doing its job behind.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
