<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Hyperlink Your Heart - cycling</title><link href="https://blog.hyperlinkyourheart.com/" rel="alternate"></link><link href="https://blog.hyperlinkyourheart.com/feeds/tag.cycling.atom.xml" rel="self"></link><id>https://blog.hyperlinkyourheart.com/</id><updated>2026-07-10T15:57:00+02:00</updated><subtitle>Until there's nothing left.</subtitle><entry><title>Home Brew Bike Speedometer</title><link href="https://blog.hyperlinkyourheart.com/speedometer.html" rel="alternate"></link><published>2026-07-10T15:57:00+02:00</published><updated>2026-07-10T15:57:00+02:00</updated><author><name>Kevin Houlihan</name></author><id>tag:blog.hyperlinkyourheart.com,2026-07-10:/speedometer.html</id><summary type="html">&lt;p&gt;I wrote a speedometer app for an old Android phone to use on my&amp;nbsp;bike.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have a phone mount on my bike, and one of the things I had a notion to use it for was to use my phone as a bike computer or speedometer. However I read that the vibration can damage a phone&amp;#8217;s accelerometer over time so I was a bit wary of using the phone I use day to day for that. On the rare occasions I need navigation, it will be worth the risk for that, but not just to know my speed on my regular&amp;nbsp;routes.&lt;/p&gt;
&lt;p&gt;Thankfully I have a couple of old phones stashed away. The one I would have preferred to use, due to its relative newness and larger screen, was a Motorola Moto G5, but unfortunately it would no longer power on. I believe the power button was dodgy when I retired it. That left me with the Samsung Galaxy S &lt;span class="caps"&gt;GT&lt;/span&gt;-i9000 (what a mouthful), a 16 year old device with a 4&amp;#8221; screen. And a removable&amp;nbsp;battery!&lt;/p&gt;
&lt;p&gt;&lt;img alt="Photo of the device with the back cover off and the battery removed" src="https://blog.hyperlinkyourheart.com/images/speedometer/battery.jpg" title="Look at what they took from us."&gt;&lt;/p&gt;
&lt;p&gt;When I powered it on I expected to find Android 2 point something, which I figured might be too old to be useful for anything. It turned out I had installed CyanogenMod on it at some point, but for some reason it was stuck in a boot loop. Once I figured out the three-finger salute to get into the recovery menu (home, power, volume up) I was able to reset it and it booted normally. The version of the Android base was 4.3.1, an improvement over 2.x at least. Nonetheless the prospect of installing an existing speedometer app did not look good. The app store was inaccessible as was much of the web due to a lack of support for &lt;span class="caps"&gt;TLS&lt;/span&gt; 1.2 (I think). I think I couldn&amp;#8217;t find a speedometer app that supported an Android version that old even if I could get an &lt;span class="caps"&gt;APK&lt;/span&gt; of&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;To be honest, I&amp;#8217;m not sure I looked very&amp;nbsp;hard.&lt;/p&gt;
&lt;p&gt;So I fired up Claude and vibe-coded&amp;#8230; &lt;span class="caps"&gt;LOL&lt;/span&gt; jk I would never. I&amp;#8217;m not really a fan of Android development but I can do it when I have to, so I set about building a basic app targeting &lt;span class="caps"&gt;SDK&lt;/span&gt; 18 as required for Android&amp;nbsp;4.3.&lt;/p&gt;
&lt;p&gt;There were some challenges to this, both due to the hardware and the ancient &lt;span class="caps"&gt;API&lt;/span&gt; version. On the hardware side, the &lt;span class="caps"&gt;USB&lt;/span&gt; port is apparently dodgy, and &lt;span class="caps"&gt;ADB&lt;/span&gt; could only occasionally see the device. The &lt;span class="caps"&gt;GPS&lt;/span&gt; is also really crap compared to recent devices. I could not get a signal in my office, or indeed anywhere indoors, and even taking it out on the roof it took quite a while to get a location. Not much of a problem for actually &lt;em&gt;using&lt;/em&gt; the app because I &lt;em&gt;usually&lt;/em&gt; cycle outdoors, but it made testing a real chore. For a while I thought I had no way of even seeing stack traces from crashes, but it seems that when you disconnect and reconnect a device you can see the logs from the period it was disconnected, so that helped a lot once I realised&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;On the software side, the Android Jetpack libraries were not available, and a lot of documentation and advice refers to these rather than the legacy library. For ages I was getting crashes due to a method I had not implemented, &lt;code&gt;onStatusChanged&lt;/code&gt;, because the documentation said it was deprecated. Turned out it was required on Android versions &amp;lt; 11, and even though I had 4.3 as my minimum, Android Studio did not flag its absence as a problem. Ah well. Should have &lt;span class="caps"&gt;RTFM&lt;/span&gt; a little more&amp;nbsp;closely&amp;#8230;&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;UI&lt;/span&gt; I implemented emphasises the current speed, but shows the max speed achieved in the session and the current altitude as well. There is also an indicator for if there is a &lt;span class="caps"&gt;GPS&lt;/span&gt; &amp;#8220;lock&amp;#8221; (just goes to false if there hasn&amp;#8217;t been a location update in the last ten seconds). I think it looks pretty&amp;nbsp;elegant.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Photo of the device displaying the app's UI - white &amp;amp; gray text on a black background. The speed (currently 0.0) is large and centred, with the max speed and current altitude below it." src="https://blog.hyperlinkyourheart.com/images/speedometer/ui.jpg" title="Not subjecting my main phone to all this dust is another advantage of using an old beater."&gt;&lt;/p&gt;
&lt;p&gt;The code isn&amp;#8217;t very interesting or anything, but &lt;a href="https://codeberg.org/khoulihan/speedometer" title="Speedometer project on Codeberg"&gt;here it is&lt;/a&gt; if you&amp;#8217;re curious or have an old Android device you would similarly like to repurpose. I don&amp;#8217;t really have any intention of maintaining it or creating releases of&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;The battery life is actually quite impressive. In some rough testing I did it lasted over 14 hours with the screen on for most of the time, but otherwise idle. I haven&amp;#8217;t tried to determine the effective battery life when using the app, but I think it will be plenty for my&amp;nbsp;purposes.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Photo of the phone mounted in my cockpit" src="https://blog.hyperlinkyourheart.com/images/speedometer/context.jpg" title="On the road."&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Selfie of me (middle-aged man) at a cafe after a cycle with a cortado in front of me." src="https://blog.hyperlinkyourheart.com/images/speedometer/selfie.jpg" title="Vibin'"&gt;&lt;/p&gt;</content><category term="Technology"></category><category term="sustainability"></category><category term="cycling"></category><category term="android"></category></entry></feed>