Building an in-app updater (OTA) in Flutter

SamJakob
SamJakob
Feb 25, 2019 · 3 min read

In many ways, Flutter is a fantastic framework for building cross-platform mobile applications however when it comes to developing features that aren’t platform-agnostic many people seem to resort to platform channel code.

At ApolloTV we try to keep as much code as possible in Dart for three reasons:

  1. It maintains the portability of our code base; should we need to implement a feature in another platform, we will have little to no code to rewrite.
  2. It reduces the learning curve for our projects; developers only have to know Dart and they don’t have to locate and interpret platform channel code.
  3. Keep-it-simple-stupid (KISS) methodology; when you start messing around with platform channels you then have to worry about communicating between the Dart code and the platform code. This can get out of hand really quickly when you throw asynchronous operations into the mix.

So, as we’re focused on keeping our code in Dart, theoretically our main obstacles are that we need to work with files, system permissions and then we need to launch an intent. File support in Dart is actually not a problem and system permissions can be overcome with a handy plugin, however we did have to resort to platform channels for the intent, but that’s about 10 lines of simple synchronous code.

Step 1: System Permissions

Thanks to a Flutter plugin called simple_permissions this wasn’t much of an issue.

Remember to add the uses-permission tag to your AndroidManifest.xml

Step 2: Filesystem

Whilst theoretically a challenge because of the platform-agnostic nature of Flutter, between the built in dart:io library and the path-provider plugin, Flutter actually provides an excellent API for manipulating files.

The key thing you probably noticed is that in Dart, you use theDirectory class to refer to a directory, and the File class to refer to a file; in my opinion, this is much more logical and aptly-named than it is in Java.

Everything is pretty self-explanatory and downloading files is an absolute breeze with Dart’s built in libraries.

NOTE: Android N support

Whilst nothing to do with Flutter, I’ve included this as it did take a bit of digging for me to get set up.

For Android N and above, a FileProvider must be used to grant the application access to a directory in external storage.

Inside your application tag in your Android manifest file, you should include a provider tag that references your File Provider class. Inside this tag, you should have a meta-data tag that lists all of the file paths the provider is allowed to access. (See filepaths.xml).

For more information about the FileProvider, see https://developer.android.com/reference/android/support/v4/content/FileProvider

Step 3: Platform Channel

The final step, is to launch an ACTION_INSTALL_PACKAGE intent. You should begin by setting up a basic platform channel.

This is a basic invokeMethod call based on the Flutter documentation.

Finally, edit your MainActivity.java file to declare the MethodChannel and execute the code to call our intent.

There aren’t any particularly advanced concepts here, as we’ve downloaded the file to external memory, so all we need to do is access it and trigger an installation.

And with that, the OTA installation is started!

ApolloBlog

The official ApolloTV blog — documenting our development process.

SamJakob

Written by

SamJakob

Full Stack Developer and Software Engineer

ApolloBlog

The official ApolloTV blog — documenting our development process.

More From Medium

Related reads

Related reads

Wm Leler
Jun 18, 2018 · 6 min read

4.1K

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade