Flutter programming on your phone

Suragch
Suragch
Feb 16 · 21 min read

A whole new meaning to mobile developer

What? They don’t have computers?! How am I supposed to teach mobile app development if the students don’t have computers?

When asked if I would teach Mobile App Development in Spring 2021 at Mongolia International University, I gladly agreed. This would be a great opportunity to systematically present Flutter, a modern cross-platform UI framework for making native apps, one that I greatly prefer over plain Android and iOS development.

As Covid-19 continued to drag on throughout 2020 and into 2021, like at many of the schools around the world, the classes at MIU were taught online. I didn’t think much about it, though, until I heard another teacher mention how difficult it is to teach programming when the students don’t have computers. I had just assumed that CS majors must have their own desktop or laptop computers. It turns out that that’s not true for some of them. With the school’s computer labs inaccessible, they were attending classes and doing their homework solely on their phones.

My course plan had been to require the students to publish their own app on one of the app stores. But without a computer that didn’t seem possible anymore. Or was it? My mind explored the possibilities.

Was there any way to get the student's computers? Some people might be willing to donate them. For example, the well-known Flutter developer Thomas Burkhart recently inspired many people by generously sending several of his old computers to developers in Nigeria and Ghana.

I know quite a few kind and generous people who would probably donate their old computers if I asked. However, this solution has its downsides. Thomas himself met a lot of problems with the sheer volume of requests and also the difficulty and expense of shipping internationally. To learn more read about his DevsHelpDevs proposal.

A new perspective

While I promote those who are doing good work like donating computers, I’m primarily writing this article for the other side, for those people whose only computer is their cell phone. The vast majority of them can’t wait around for someone to give them a laptop.

Whenever possible I prefer to empower people themselves and put the responsibility into their own hands. This type of solution is scalable because it depends far less on outside support.

That leads me to the following option:

Teach the students to program on their phones.

That sounds crazy, I know. Nobody does that seriously, right? Maybe for fun or practice, but not to actually build a production app.

Think back to how people programmed back in the early days. I first heard about this from Uncle Bob (Robert Martin) who talks about how people used to write their programs by hand on coding form like this one:

Fortran coding form

The lines of code that were handwritten on that form would then have to be transferred to punch cards like this:

Fortran punched card

You needed to use one card for every line of code. For example, the card above is Z(1) = Y + W(1). An entire program would look like this:

Punched card program deck

Finally, you would feed the cards into a computer so that you could run your program. And you might get the results back on more punched cards.

Think about it. If you weren’t the one punching and running your own program, you might have to wait until the next day to learn the results! Even if your program was bug-free, hopefully, no one else mixed up a 0 and a O or got a card out of order, because fixing that would take another day.

Can you believe that thousands and thousands of people learned to program using coding forms and punch cards?

With that perspective now, does it still sound so crazy that there might be a way to teach mobile app development where the students’ only computer is their phone?

Requirements

There are two main requirements for enabling people to develop on their phones. The first is that the entire process needs to be possible to do completely on the developer’s device. Second, it must be affordable. People who can’t afford to buy a computer yet also can’t afford to pay high prices for online services.

In exploring how to write code on one’s phone, I considered several different options. The first that came to mind was DartPad, which allows you to write and run Dart programs and even simple Flutter apps online. This does make it a good tool for learning and testing things in isolation. However, DartPad doesn’t support multiple files or importing third-party libraries, so it’s not really a solution to make a real app that you’ll publish to an app store.

Another option I heard about was GitHub Codespaces, which is a cloud-based development environment and includes an IDE that you can use in your browser. Basically, it looks like a web app version of Visual Studio Code. That would be great! Unfortunately, it’s still in private beta and I’ve been on the waitlist for months. Even if I get in by the time classes start, my students wouldn’t be able to. Another question is cost. It’s apparently free during the beta, but will it be prohibitively expensive to use after that?

I also considered installing an IDE like VS Code or Android Studio (with its Android emulator) on a remote Linux machine. However, the main problem here is the cost. To cost rent a VPS with enough RAM to run a GUI-based OS plus the IDE and emulator would be too high. Most people recommend a minimum of 8GB of RAM for mobile app development. I used to use 4GB on a Mac Mini to make iOS apps and it was painfully slow. You’d be looking at about $40 USD per month for a server with 8GB of RAM.

There is a path to success that would work, though.

The plan

These are one possible set of steps that will allow you to publish a mobile app from your phone:

  1. Install a terminal app on your phone
  2. Set up a remote Linux server
  3. Install command-line-based Flutter and Dart on the server
  4. Develop a Flutter project
  5. Sync code between the phone and the server using GitHub
  6. Run unit and widget tests on the server
  7. Build a Flutter web app for UI/UX testing
  8. Use an online service to build release versions for Android or iOS
  9. Submit the app to the app store

Doing all this on a phone definitely won’t be easy, but for someone with sufficient motivation and determination, it will be possible.

The following sections will walk through each of these steps in detail. I’ll actually publish an app to Google Play from my own phone to show that it’s possible.

Installing a terminal app

You’re going to be doing most of the testing on a Linux server, so you need a way to access the server from the command line.

Note: I’m writing and testing this article from the perspective of using an Android phone. I’ll provide a few links for iPhone users, but you’ll have to do your own testing.

On Android, you can install Termux. iPhone users can search for “ssh client” or check out this article here for suggestions.

This is a sample of what the Termux app looks like:

Termux app for Android

Open the app and try writing a Linux command. For example, print the working directory like so:

pwd

This shows:

/data/data/com.termux/files/home

If you want to learn more about Linux commands you can watch this video or read this tutorial.

The main command you’re going to need on the phone side is ssh, which you’ll use to log in to the remote Linux server that you’ll set up in the next section. The ssh command is not installed by default, but you can install it as follows from within Termux:

pkg install openssh

ssh is set up. All we need now is a server.

Getting up a remote Linux server

For this step, the key requirement is finding the cheapest server that will run Dart and Flutter. Since you’ll only be working with the command-line version of Flutter and you don’t need to run a heavy IDE or emulator, a 1GB virtual private server (VPS) will be fine.

As a teacher, I can set up a Linux server with accounts that my students can log in to. However, the following are some ideas for those of you who need to find your own server.

I’ve used Digital Ocean for my servers for over a year, and I’ve heard Vulr is also good. I chose Digital Ocean because they have good tutorials, they’re reliable, and they’re not too expensive. However, even Digital Ocean and Vulr cost about 5 USD per month for a 1GB server, which is $60 a year. That’s still expensive for students and some new developers. You can find even cheaper deals on LowEndBox from time to time if you scour the old posts. For today’s tutorial, I’m going to use a 1GB VPS that I found on LowEndBox for $11/year.

Note: Just be aware that a lot of the companies on LowEndBox end up going out of business. Some I’ve used successfully for years and others not so long. Keep your data backed up. Or, if you end up choosing Digital Ocean, you can use my referral link. You get a discount and I get credit toward my account.

After getting the VPS, I chose Ubuntu 20.04 for the operating system.

Installing Flutter and Dart

Once you have your server, you can log in from Termux (or whatever ssh client you are using on your phone).

ssh root@107.173.555.555

Change the IP to the one you got with your VPS.

There are a few administrative tasks you should probably do before going on, but rather than describe those here I’ll refer you to the article Initial Server Setup with Ubuntu 20.04.

Go to the Linux Install page for Flutter in your phone browser. Then long click the download button so that you can copy the current stable release download link.

After that go back to the terminal (where you are logged into your VPS) and use wget to download the file:

wget https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_1.22.6-stable.tar.xz

Extract the download using the following command:

tar xf flutter_linux_1.22.6-stable.tar.xz

Update the filename to whatever the stable version is currently.

You can delete the download now:

rm flutter_linux_1.22.6-stable.tar.xz

Notes:

  • Termux has a tab key in the menu bar above the keyboard that you can use to auto-complete long filenames so that you don’t have to type all that on a soft keyboard.
  • You can also experiment with different keyboards that make command line and code input easier.
  • If you stay logged in to the server for a long time, the terminal might become unresponsive, in which case you’ll have to force kill the process in Termux. To do that, long-press the screen, choose More… and then Kill process.

To run Flutter and Dart commands from the command line, you need to add Flutter (which includes Dart) to your path. The place you do this on different Linux distributions is different.

In your home directory, list all the files there like this:

ls -al

Ubuntu uses .bashrc to initialize the path, so edit that file:

nano .bashrc

Then add the following line to the bottom (assuming you extracted Flutter to your home directory):

export PATH="$PATH:$HOME/flutter/bin"

Remember that you can copy and paste in Termux by long-pressing the screen. Save the file and exit nano.

Then refresh the new bash settings:

source .bashrc

You can find more directions about adding Flutter to your path here.

Now run:

flutter --version

That probably didn’t work because Flutter has several dependencies that your VPS probably doesn’t have installed, so you’ll see an error message like one of these:

Error: Unable or find git in your PATH
Missing "curl" tool. Unable to download Dart SDK
Missing "unzip" tool. Unable to extract Dart SDK

Just install the missing tools with apt-get one at a time until you no longer get any errors when you try to run flutter commands.

sudo apt-get install git
sudo atp-get install curl
sudo apt-get install unzip

Eventually, when you run flutter --version you should see something like the following:

Flutter 1.22.6 • channel stable
...
Tools • Dart 2.10.4

Flutter is all set up!

Developing a Flutter project

You can do anything Flutter-related on the command line. In fact, the IDEs like Android Studio and VS Code all use the Flutter command-line interface (CLI) internally.

Go to whatever directory you want to put your projects in. Then create a new Flutter project like this:

flutter create my_project

You can of course use nano or vi to edit the project files and do your coding. If you go that route I’d use vi (or vim). It has a steep learning curve but once you learn the shortcuts it’s pretty powerful. (That’s what people say anyway — I wouldn’t know.)

Another option would be to use an IDE app on your phone. There are quite a few. I experimented with three of them and Acode seems pretty good. It’s not specifically designed for Dart, but it still makes code editing a lot easier than doing it in nano or vi.

Acode app for Android

If you do the file editing on your phone, then you’ll need a way to get those changes to the server. You could copy and paste between Acode and nano/vi running in Termux, but using git would probably be easier. I’ll describe that in the next section.

Syncing changes with git

To write code on your phone and run it on the server, you need to sync the changes between them. To do that you can use git with GitHub as the central repository. After you finish making an edit on your phone, you’ll push the changes to GitHub. Then before you run the code on the server, you’ll pull the updates from GitHub.

I won’t go into all the details of how to do that in this article, but let me outline the steps you’ll need to take with links for how to accomplish them:

  1. Create a repository for your project on GitHub. Some things are difficult (or impossible?) to do with the mobile version of the GitHub site. In your browser, though, you can request to view the desktop version of the site. For more help with steps 1–4, read How to Push an Existing Project to GitHub.
  2. Initialize your project with git on the server.
  3. Connect your server’s git project to the GitHub repository.
  4. Push your code from the server to GitHub.
  5. Install git on your phone. You can do this in Termux with pkg install git.
  6. Clone the GitHub repository on your phone. Don’t do it in the home folder of Termux, otherwise, your code editing app won’t have access to it. Instead, enable shared storage in Termux with termux-setup-storage and then cd ~/shared to find a good clone location.
  7. Make edits to the code on your phone. You can use A code or whatever app you like for that.
  8. Add, commit, and then push those changes to GitHub from the phone.
  9. Switch back to the server and pull the changes from GitHub.

So now you can make changes, but you don’t actually know if your code has any bugs.

Debugging a Flutter project

Make sure you’re in the root folder of your project in the server terminal. Run the following command:

flutter analyze

This will perform a static analysis of your project and tell you if there are any compile-time errors. Hopefully, you’ll see something like this:

Analyzing my_project...No issues found! (ran in 9.1s)

If there are any errors, though, fix them and then run the analysis again. (I’m actually getting to be a bigger fan of vi for making changes like this. It’s easier than syncing with GitHub and jumping back and forth.)

Static analysis can help you find compile-time errors, but you’ll need to run the code to find the run-time errors. Obviously.

Running Dart code with tests

Eventually, you’re going to run the Flutter web version of your app to see how the whole app is working. However, you can check individual chunks of your code by running tests. One great thing about testing Flutter apps is that the tests don’t require a graphical interface. That means that in addition to testing pure Dart logic, you can also test UI widgets — all from the command line.

If you created a new Flutter project, there is already a default test in test/widgets_test.dart. Run that test with the following command:

flutter test

My server gave me the following result:

00:34 +1: All tests passed!

Learn more in the Testing Flutter apps documentation.

Many developers don’t write tests at all. They know they should but they think writing tests slow them down. So they skip them. For developers who program on their phones, though, writing tests can literally be the fastest way to get results. Mastering this skill will not only help you now but will also make you a superior developer in the long run.

Publishing a Flutter web app

The fastest way to get your whole app running and see what the UI actually looks like is to build the web version of your Flutter app.

At the time of writing Flutter, the web is still in beta, so you’ll need to run the following commands to enable web builds:

flutter channel beta
flutter upgrade
flutter config --enable-web

Go to the root of your project. If your project didn’t support the web before, then you can add that with the following command:

flutter create .

Now build the web project like so:

flutter build web

All the files for your web app are now in the build/web folder. The next step is to make a web server so that you can view your app in a browser.

You already have a server, so you might as well use it as a web server, too. To do that you can use Nginx. There’s a longer explanation of how to set Nginx up here, but I’ll include the minimal instructions below:

Run the following command to install Nginx:

sudo apt-get install nginx

If you followed the advice in the server setup link I gave you earlier, then you have a firewall enabled. However, it’s currently blocking HTTP connections. To unblock them run the following command:

sudo ufw allow 'Nginx HTTP'

Now putting your IP address in your phone’s web browser should give you the default Nginx index.html file.

Screenshot of default Nginx setup

Now all you need to do is point Nginx to your Flutter web app.

Create a new site config file:

sudo nano /etc/nginx/sites-available/my_project

If nano doesn’t work for you try vi. (Termux was preventing me from using the arrow navigation on my keyboard so I had to use the vi navigation shortcuts.)

Then paste in the following content:

server {
listen 80;
root /home/suragch/my_project/build/web;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}

But change the path after root to wherever your project’s build/web folder is. Save and exit the file.

Now remove the Nginx default page:

sudo rm /etc/nginx/sites-enabled/default

And add your app:

sudo ln -s /etc/nginx/sites-available/my_project /etc/nginx/sites-enabled

Then restart Nginx:

sudo systemctl restart nginx

Refresh the browser page with your IP address and you should see your app show up:

Now make a change to the code and run flutter build web again. (For example, I changed Colors.blue to Colors.green in lib/main.dart.) Then refresh your web browser:

You now have a way to run and visually test your Flutter app! It’s not exactly hot reload, but it’s a whole lot better than code forms and punch cards, isn’t it?

Note: Setting Nginx up to serve the build folder is convenient for development, but on a production web app you should copy the contents of the build/web folder somewhere else and point Nginx to that.

After you’re finished with development, the next step is to publish your app to an app store.

Publishing your app

I think I might have trouble getting the default counter app published to Google Play or the App Store. So to test this step I’m going to use an app I made previously for an article I wrote at raywenderlich.com. Normally I couldn’t use that content for an educational article like this one, but Ray kindly gave me special permission to use the app as an example here. I won’t be describing how to make the app itself, so check out the article I linked to above if you want to know how it was made.

The app already exists on GitHub so I’ll follow the same steps I described previously to get it running as a web app on the server. The app is called Moola X and is a foreign currency exchange tool. Here’s what it looks like running on a phone browser:

Moola X app running on the web

Note: I made this app using my laptop computer over a year ago and even the updates I made to it just now were done with my computer. You can call this cheating since I didn’t develop it all on my phone, but I’m trying to get this article published before my class starts, so I needed to take some shortcuts. If it wasn’t obvious already, developing on a phone is decidedly more difficult than using a full-size computer. There is nothing I did on my computer, though, that I couldn’t have done more slowly on my phone.

Publishing on Google Play requires a $25 USD one-time fee while publishing on the Apple App Store requires a yearly $99 USD fee. That makes Google Play the clear winner as the first publishing target.

It should be possible to create a release version of an Android app directly on the server without Android Studio if you install Gradle. The resulting APK or AAB file could then be uploaded to your Google Play developer account. I decided to pursue a different route, though.

I’d heard about an online CI/CD service provider called Codemagic that takes a GitHub repo and uses it to build the production app binary on their own computers. I normally like to avoid third-party services and we don’t really need them to make the Android app. However, a key advantage here is that the apps are compiled on Apple computers. That means you could just as easily use them to publish an iOS version of your Flutter app. That’s something you could never do on your Linux server. As for cost, Codemagic gives 500 free build minutes per month. That’s more than enough to publish an app as long as you do all the testing on your own server as described above and then use Codemagic to build the final release version of the app.

Note: I don’t have any connection to Codemagic and don’t get any benefit if you use them. Feel free to suggest an alternative online service in the comments below. However, they do specifically support Flutter, and the Flutter team has endorsed them in the past.

Codemagic, if you are reading this, consider asking someone to write some step-by-step tutorials that go through exactly what a new user needs to do to get an app published. Leave no step out. Have one tutorial for publishing a Flutter Android app, another tutorial for publishing a Flutter iOS app, and so on for all of the options you offer. You do have a lot of good documentation and I like the articles on your blog, but it was pretty intimidating getting set up for the first time.

Here are the basic steps you need to follow to get set up with Codemagic:

  • Sign up for a Codemagic account
  • In Codemagic add the git repository for your app
  • You’ll need to create a keystore to sign your Android app. To do that you need to use keytool from the Java Development Kit (JDK) framework. So on your server install Java. There are good directions here. Then generate the keystore file by using keytool like this. Don’t forget your password, don’t lose your keystore file, and don’t commit the file to GitHub. If you lose the file or forget your password you won’t be able to update your app in the future.
  • Download the keystore to your phone. You can use scp for that. Here’s an example of what that might look like. Your details will be different, of course.
scp suragch@107.173.555.555:/home/suragch/moolax_keystore.jks .
  • Follow the directions here and here to prepare the Android app for release. There are several photo editing apps or online image resizing tools that you can use to create image assets of the correct size.
  • In Codemagic upload the keystore file and input the password and alias information. You should also make sure that the Android settings are for building a release. I also selected AAB and universal APK as the build outputs. The AAB is what you’ll put on Google Play, but the APK you can install directly on your phone.
  • Make sure all your local changes are pushed to GitHub (whether you made them on your phone or the server). Then click Start build in Codemagic.

It took about five minutes to build the app and when the build was finished, Codemagic sent me an email with links to the AAB and APK files. I downloaded and installed the APK and…

…it didn’t work. It just crashed when I tried to open the installed app on my phone. Sigh.

The next day…

After fixing a flutter analyzer warning that I had previously ignored, I got an Android app build from Codemagic that worked. In the future, adding integration testing and adding them to the Codemagic build would also help diagnose build errors.

Anyway, here’s what the native Android build looks like running on my phone:

Moola X running as an Android app

This is progress!

It would be possible to put the APK as a direct download on our server and call it finished, but to make it more widely available and to monetize the app, it would be better to put it on Google Play.

To publish on Google Play you need to sign up for a developer account and log in to the Google Play Console. The are directions are here. As I mentioned earlier, the fee is $25 USD. Students or developers who can’t afford this could team up and share an account with someone else.

Once you log in, you can press the Create app button and start filling out all the required information. Most of it was pretty straight forward and Google has done a good job making the site accessible for phones. I uploaded the AAB file that I got from the Codemagic email. For the app image, I used an online site that would resize a photo to the required dimensions. The most difficult requirements, though, were the 7-inch and 10-inch screenshots. In the end, I uploaded a cropped version of my phone screenshot. We’ll see if that passes the review.

Screenshots from filling out the required Google Play information

I succeeded in submitting the app for review. There is nothing more to do until I hear back. I’ll call that a success! There’s no part of the app development process that you can’t do on your phone.

Update: The app was accepted on the first try:

Even after three months, though, it made a total of $0 dollars. Not a hopeful sign for developers who want to save up enough to buy a computer. Maybe ads would have been a better choice. I gave up and just made the app free. Here it is.

Concluding thoughts

Programming mobile apps on your phone are no trivial task. However, a sufficiently motivated individual is fully capable of accomplishing it. The required process will even help the “mobile” developer learn skills that a “laptop” developer might miss, skills like server administration, source control with git, unit testing, and CI/CD workflows.

For those of you reading this who only have a phone, I recommend you start making your first app. You can try selling it on Google Play or putting ads in it, but chances are you aren’t going to make a ton of money like this. For your second app, I recommend trying to get a freelance job on one of the many sites looking for app developers. Save your money and when you’re able, buy a cheap laptop or desktop. Work up from there. When you get a job interview tell the employer about how you started by programming on your phone. Show them what you accomplished. That would impress anyone.

And for those of you reading this who have programming experience, consider mentoring someone through the process of becoming a developer. The first step may be to walk with them through the steps outlined in this article. You know if they are serious enough to do that, then they’re serious enough to go a lot further.

For me? I hope I never lose my computer, but if I do, I know how to use my phone!

Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm

Flutter Community

Articles and Stories from the Flutter Community

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store