Build Your Own Flutter Plugin Using Android Native Kotlin — Part I

Kathryn
Geek Culture
Published in
5 min readMay 27, 2021

This tutorial is a Kotlin version of this tutorial: “How To Write a Flutter Plugin” from Google Developers Colabs. (The original tutorial was written in JAVA.)

The Goal of this tutorial is to go through:

  • When do you need a Flutter Plugin project.
  • How does Flutter communicate with Android native code/library in Kotlin. (Read the original tutorial for iOS alternatives).
  • How to config a Flutter Plugin project from scratch with IntelliJ IDEA.
  • Following the original tutorial to build an example app of MIDI keyboard (with Flutter front-end) which uses Android native library: android.media (with Kotlin) through the Flutter Plugin API (with Dart) you will build.

When do you need a Flutter Plugin project?

Flutter Plugin is an advanced topic in Flutter development. Many developers do not need to build Flutter Plugin in their Flutter development. However, if you want to do the following task, you might need one:

  • If you want to build a Flutter API for other Flutter projects to use,
  • and / or through such API, you enable Flutter to communicate with platform-specific native code (e.g., JAVA or Kotlin for Android, and Objective-C or Swift for iOS).

How does Flutter Work?

Before we start the tutorial, we need an introduction of how does Flutter work in general. Flutter is a cross-platform development framework, which allows you to build UI for different platforms, i.e., Android, iOS, or Web (See also supported platforms), with one code base. Flutter is written in Dart language, and it takes care of the underlying integration for different platforms, so you don’t need to build a separate development, e.g., using Swift for iOS and Kotlin/JAVA for Android, for the same app.

It sounds terrific, isn’t it! Since Flutter is a framework which wraps the native Android and iOS platform-specific codes to make such integration possible, there is an intermediate Dart layer which handles the communication between <Flutter vs. Android native> or <Flutter vs. iOS native>. In other words, if you don’t need the Android or iOS native libraries to achieve your task, then you don’t even need to worry about this.

The architecture of Flutter framework is illustrated:

The top level (Green) is the general UI/UX framework in Dart, and the bottom level (Yellow) is the platform-specific Embedder layer, which includes Native Plugins that can be imported with Kotlin/JAVA for Android or Swift/Objective-C for iOS etc. Then, the “Platform Channels”, located in the middle level (Blue), is responsible for the communication between the top (Dart) and bottom (platform-specific native code)level.

The architecture of Platform Channels is illustrated:

The MethodChannel manages the platform-specific communications between the Flutter app client and the iOS /Android host, so one can write up AppDelegate (iOS) or Activity (Android) class to interact with native APIs.

For a Flutter Plugin project, we are to replace the Green box with our own class to: (1) handle the method call, and (2) define each method’s behaviour.

This tutorial is going to guide you from head-to-toe to build such a Flutter Plugin which would have:

  1. PianoPlugin class (written in Kotlin):
    It served as the Factory, i.e. MethodChannel, to handle the method call from Flutter, and then it calls the corresponding method in Synth class, and return the result to Flutter.
  2. Synth class (written in Kotlin):
    It has the actual implementations of calling Android native APIs to generate MIDI sounds.
  3. Flutter API (written in Dart):
    It provides the Flutter interface for your clients to call the Plugin methods.
  4. Demo app (written in Dart):
    In the end, we will have the keyboard layout built with Flutter UI, and each key press will call the methods in Flutter API to create the sounds. In other words, this is a Flutter client which showcases how to use your API.

Now let’s get started!

Create a Flutter Plugin project in IntelliJ IDEA

In IntelliJ, click File > New > Project > Flutter:

Then, choose your project name and in Project type drop down, pick Plugin. In this demo, Kotlinwill be used as Android language, and only Android platform will be showcased.

You can as well change Organization to domain names that you like to name it, e.g., you can change it to “magicmidi.com”. Note that it has to be a dot segmented form, and this will become the prefix name of your native plugin package. Here, let’s just leave it as is.

Click “Finish”, and Flutter will create a template Plugin project for you.

Project Structure Explains

In the new plugin project you just created, you will see 3 high level packages: android, example, lib

android

All the native Android codes (i.e., Kotlin) go to this module, and thus our PianoPlugin class and Synth class will be located under android > src.main > $your-native-package-name >

lib

In regular Flutter project, lib is where the main.dart located (i.e., where the application is initiated from). But since now we are building a “Plugin” and not an actual application, the piano.dart is a Flutter API which can be called by a Flutter app.

example

This is a fully functioning demo Flutter app, which includes UI, and the associated functions which showcase how to call the Flutter API in piano.dart. You will find a main.dart as the entry point of the demo app. When you run the emulator, this is the actual app shown on the virtual phone.

In the part II of this tutorial, I’ll share the actual Kotlin and Dart codes to these abovementioned files to bring this API to live.

--

--