Ok. I spent the weekend completely reversing Kiiroo's firmware loading protocol, and now have my own loader that works flawlessly. I'm working on getting a web version of this up and running so people on mac/linux/android can at least fix things up themselves.
For anyone interested in technical details, here's what's going on with that reboot fix.
I noticed the same problem when loading from my android tablet while working on the firmware loader code. It would get to the end, do a "Finalizing", then just stall.
After the firmware is loaded to the device, a couple of integrity checks are done, and then the device reboots into the regular application mode (blinking blue light). During this, the launch disconnects from bluetooth. After that reboot, the application needs to reconnect to the launch and sends a couple of commands to the cmd/data characteristics in order to "lock" the Launch back into app mode, otherwise if you power down and restart it'll be back in bootloader mode again.
Unfortunately, the algorithm to reconnect after reboot in FeelConnect is dumb. Lots of random sleeps and retries, and it could very well be that the phone doesn't disconnect correctly so you may not even see the Launch after it reboots. The reason this always works on iPhone is that iPhones are extremely predictable. They're all the same. Android phones, on the otherhand, you never know what you're going to get, the bluetooth response/stacks can vary widely. Kiiroo does not seem to have engineers equipped to handle this kind of variation.
For this fix, what you're doing when you turn bluetooth off/on is basically clearing out the connections, so when you turn bluetooth back on, the app starts scanning again, and it can finally connect and send that "lock" command.
Now that I know how all of this works, I'm trying to build a utility to send those commands over without having to guess the point at which you need to turn things on/off. This should hopefully be the beginning of the end of firmware reloading bricking.