Suppose someone came to talk to you and said, “I need your help. I have a Raspberry Pi-based robot and I want to develop a custom Android app to control it.” If you are like me, you’ll think about having to get the Android developer tools updated, and you’ll wonder if you remember exactly how to sign a manifest. Not an appealing thought. Sure, you can buy things off the shelf that make it easier, but then it isn’t custom, and you have to accept how it works. But it turns out that for simple things, you can use an old Google Labs project that is, surprisingly, still active and works well: MIT’s App Inventor — which, unfortunately, should have the acronym AI, but I’ll just call it Inventor to avoid confusion.
What’s Inventor? It lives in your browser. You lay out a fake phone screen using drag and drop, much like you’d use QT Designer or Visual Basic. You can switch views and attach actions using a block language sort of like Scratch. You can debug in an emulator or on your live phone wirelessly. Then, when you are ready, you can drop an APK file ready for people to download. Do you prefer an iPhone? There’s some support for it, although that’s not as mature. In particular, it appears that you can’t easily share an iPhone app with others.
Is it perfect? No, there are some quirks. But it works well and, with a little patience, can make amazingly good apps. Are they as efficient as some handcrafted masterpiece? Probably not. Does it matter? Probably not. I think it gets a bad rep because of the colorful blocks. Surely it’s made for kids. Well, honestly, it is. But it does a fine job, and just like TinkerCad or Lego, it is simple enough for kids, but you can use it to do some pretty amazing things.
How Fast?
How fast is it to create a simple Android app? Once you get used to it, it is very fast, and there are plenty of tutorials. Just for fun, I wrote a little custom web browser for my favorite website. It is hard to tell from the image, but there are several components present. The web browser at the bottom is obvious, and there are three oval buttons. The Hackaday logo is also clickable (it takes you home). What you can’t see is that there is a screen component you get by default. In there is a vertical layout that stacks the toolbar with the web browser. Then the toolbar itself is a horizontal layout (colored yellow, as you can see).
The black bar at the bottom and the very top bar are parts of the fake phone, although you can also pick a fake monitor or tablet if you want more space to work.
What you can’t see is that there are two more hidden components. There’s a clock. If you are on the home page for an hour, the app refreshes the page. There’s also a share component that the share button will use. You can see three views of the app below. There are three views: a design view where you visually build the interface, a block view where you create code, and the final result running on a real phone.
Code
Putting all that on the screen took just a few minutes. Sure, I played with the fonts and colors, but just to get the basic layout took well under five minutes. But what about the code? That’s simple, too, as you can see.
The drab boxes are for control structures like event handlers and if/then blocks. Purple boxes are for subroutine calls, and you can define your own subroutines, although that wasn’t needed here. The green blocks are properties, like the browser’s URL. You can try it yourself if you want.
Rather than turn this into a full-blown Inventor tutorial, check out any of the amazingly good tutorials on the YouTube channel, like the one below.
Half the Story
Earlier, I mentioned that your friend wants a robot controller to talk to a Raspberry Pi. I was surprised at how hard this turned out to be, but it wasn’t Inventor’s fault. There are three obvious choices: the system can make web requests, or it can connect via Bluetooth. It can also work with a serial port.
I made the mistake of deciding to use Bluetooth serial using the Bluetooth client component. From Inventor’s point of view, this is easy, if not very sophisticated. But the Linux side turned out to be a pain.
There was a time when Bluez, the Linux Bluetooth stack, had a fairly easy way to create a fake serial port that talked over Bluetooth. There are numerous examples of this circulating on the Internet. But they decided that wasn’t good for some reason and deprecated it. Modern Linux doesn’t like all that and expects you to create a dbus program that can receive bus messages from the Bluetooth stack.
To Be Fair…
Ok, in all fairness, you can reload the Bluetooth stack with a compatibility flag — at least for now — and it will still work the old way. But you know they’ll eventually turn that off, so I decided I should do it the right way. Instead of fighting it, though, I found some code on GitHub that created a simple client or server for SPP (the serial port profile). I stripped it down to just work as a server, and then bolted out a separate function bt_main()
where you can just write code that works with streams. That way, all the hocus pocus — and there is a lot of it — stays out of your way.
You can find my changes to the original code, also on GitHub. Look at the spp_bridge.c file, and you’ll see it is a lot of messy bits to interact with Bluez via dbus. It registers a Profile1
interface and forks a worker process for each incoming connection. The worker runs the user-defined bt_main()
function, which will normally override. The worker reads from the Bluetooth socket and writes to your code via a normal FILE *
. You can send data back the same way.
Here’s the default bt_main function:
<div> <pre>int bt_main(int argc, char *argv[], FILE *in, FILE *out) { // Default demo: echo lines, prefixing with "ECHO: " fprintf(stderr,"[bt_main] Default echo mode.\n"); setvbuf(out,NULL,_IOLBF,0); charbuf[1024]; while(fgets(buf,sizeof(buf),in)){ fprintf(stderr,"[bt_main] RX: %s",buf); fprintf(out,"ECHO: %s",buf); fflush(out); } fprintf(stderr,"[bt_main] Input closed. Exiting.\n"); return0; }</pre>
bt_main
function is easy to write and lets you focus on solving your problem rather than how to set up and tear down the Bluetooth connection.Next Time
Next time, I’ll show you a more interesting bt_main along with an Android app that sends and receives data with a custom server. You could use this as the basis of, for example, a custom macropad or an Android app to control a robot.
I’m so glad this is still around! I used it many many years ago to turn my phone into a remote for an electric skateboard using the tilt sensor and recently I’ve been noodling on how to trigger the Halloween candy launcher cannons I’m working on.
Thank you MIT!
If you are like me you will wonder why you would build something as potentially long-lived as a robot control system on a moving target like Android.
I hate apps, yet still have a handful of necessary ones that were written 10 years ago and I will have to keep an older phone around or patch them to support newer versions of Android.
A Pi is completely able to run a web based interface, and web to usb is a thing. I also guarantee that web compatibility will be much better long run than Android compatibility.
You do you, apps suck because the phone OS people are in control. I use FB, Instagram, YouTube etc in my browser on mobile. Granted my phone has a 7.6″ screen and 12GB of RAM, but at $200 used it’s not impossible, and a heck of a lot easier than dealing with the poorly optimized apps scraping my phonebook and scamming my friends. I need a sandbox on my phones to deny apps permissions. Did you know apps can all access localhost with no permission and exfiltrate any data they can put there? I’m not a fan.
If someone comes to asks you to develop an app to control a robot, the correct answer is to stare at them until they leave in shame.
Sorry I’m griping, just find apps very irritating because they got so horrible. I have ADD and the ads are an instant lose for me, if I could pay $5 or $10 for a decent file browser or IR remote app I would (the manufacturer bundled one did nothing but serve me ads for TV shows, so intrusively that the whole button panel was ‘dripping’ in blood to advertise a serial killer. Which I found very poor taste.)
Now that you say AI, I don’t know if your name is A-Eye, or A-ELL 😂😂
Well written article and good job explaining the Bluetooth connection. But I would still try to steer people toward a browser-based scheme if there is compute power to spare.
android is a mixed bag. i definitely have ancient apps that still work without updates. and others that have needed updates over the years. especially if you want to interact with background execution or notifications. and of course a third class of apps, those that needed updates and haven’t received them.
lately, i’m infuriated by apps that have been updated but still don’t work. for example, i have two apps i made that are almost identical in one component. i updated one to the new way of background execution and it ‘works’ but it doesn’t really. i ask it to run a task “in exactly 5 minutes” and hours later it still hasn’t been run. i understand that android needs to contend with bad apps like facebook but there has to be a way to run tasks reliably in the background. my app doesn’t hurt battery life noticably and even if it did, i want it to run. the battery is there so it can do things i want it to.
so i haven’t updated the second app yet. so its background execution doesn’t work at all. i just don’t feel much motivation to update it, just to have it not-really-work.
android’s battle with background execution reminds me of an airline battle…in the late 90s there was a fad of oversized roll-on luggage (it’s not a fad anymore, it’s just the status quo today). and it would not fit under the seat in front of you. and the airline provided a mockup space in the terminal where you could test if the bag would fit — a luggage gauge. and it would not fit in the luggage gauge either. but people were bringing them on the airplane anyways. so the airline retaliated by shrinking the luggage gauge.
the permissions model in android is so well-designed at a high-level but every time they face an enforcement decision, they get it wrong in every detail. breathtaking wrongness.
From App Inventor’s ToS:
Not great.
Do not give MIT your personal information. MIT is not your friend.
Q.v., the Lincoln Laboratory, and their many other governmental entrails.