An Android app adventure

A project log for uECG - a very small wearable ECG

It's cheap, doesn't use a specialized heart rate AFE and can blink LEDs with your pulse :)

the_3d6the_3d6 02/17/2020 at 20:440 Comments

We started writing Android app at the beginning of last year. Since most of the development was on my (Dmitry’s) Meizu phone, that’s the only phone it was tested on. Only after some time we found that not all phones on our team were able to run the application. A lot of things happened - Maker Faire, factory production, then manual assembly, packaging and distribution of devices. Only a couple of weeks ago we realized that a problem with the application could affect many users.

I’m a beginner Android developer. To be precise, I only wrote one Android app - once I copy-pasted something that works kinda the way I like, and since then I made many variations of that first app for different purposes. Even BLE functions were partially inherited from previous projects (these I proudly wrote myself using Android documentation, because I couldn’t find any example simple enough to understand). With one important difference: in uECG protocol, data stream really pushes capabilities of BLE advertising mode (not theoretical limit, but a practical one, where really a lot of packets could be lost). And I wanted advertising mode because it’s much simpler to implement on the device side. Yes, about the device side: there’s one thing - we are not using softdevice, for a number of reasons (microseconds-precise timing, LEDs driver, 1 ms data processing cycle - all of that is based on interrupts and softdevice would delay them. It kinda can be workarounded and/or reduced - but why restrict future development options?). So I’ve implemented advertising protocol manually. And it worked with my phone just fine (as well as team members’ phones at the moment), everything was going well, until we got a new phone and started to test with it. To my surprise, nothing worked at all - that new phone was just ignoring packets. I’ve started to dig into BLE documentation and wrote a BLE sniffer. In a few days I found and fixed several things that weren’t compliant with BLE specification (yet worked on older phones). And… nope, it still didn’t work on the new phone. Except for some strange cases: once in 10s or 100s of thousands packets something was getting through. I started to suspect that packets that actually got through were corrupted but by chance had correct CRC. Sure enough, after 3 days of experiments I found that custom data field length should be different from what’s described in BLE documentation (at least from that particular document I was using: actually there is no single point where you can get all the data you need). As soon as I changed it, everything started working on all of our phones… except for my own old one! After some more guessing I realized that Android banned my application from using any active form of BLE scanning - so when some other app was scanning BLE in the background, my app also received the data and worked just fine. But as soon as other, non-banned app, was turned off - my app stopped working too. I still have no idea why it happened and what to do about it (not a single hint anywhere), but apparently this is a problem of my particular phone and my Android being not happy with my code. I can live with that! :)

App in play store:
Source code: