Writing a custom Android launcher using Flutter
Tags: flutter, android
Published: 2020-01-30 17:50:38

---
title: Writing a custom Android launcher using Flutter
published: true
description: How to create an Android launcher using Flutter
tags: flutter,Android
---

Have you ever wondered about how to create your own custom launcher for your Android device? Well, I haven't - BUT as I wanted to play around with Flutter and did not want to create yet another Todo App, I changed my mind.

# So - what's in this post?
The main takeaway will be what to do to create a launcher app. Beyond that, I'll show you a few parts of the launcher I wrote. 

As I'm not an expert Flutter developer, this post will not show you how to build a full app - there's already enough good material freely available. 

# Now how does this work?
To make things short, I found the necessary information in this reddit: [Android Launcher in Flutter](https://www.reddit.com/r/Flutter/comments/bkknj9/android_launcher_in_flutter/)
So all credit goes to the person who answered that question.

For your app to become a launcher, you'll just need to add these two categories to your activity in AndroidManifest.xml:
```
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
```

That's really all there is to it.

If you know how to proceed from here, feel free to stop reading now. Or you might follow along to see what I have built. It's up to you...

# The launcher

## Motivation
As an elderly person I know (let's call her "mother") thought about getting a Smartphone, I thought about ways to make her start easier (and of course I wanted to reduce my "support efforts"). So I built a custom launcher, that only offers the bare minimum of functionality.

My second motivation was to try things and find out, how Flutter works.

## Features
My launcher consists of two very simple screens. There's of course a home screen to launch apps and there's a second screen where you can configure a few things.

## Home screen
The home screen needs to be dead simple. There are four apps, my "users" are typically going to need:
* Dialer
* Text messages
* Camera
* Favourite messenger

Therefore, the home screen will be composed of four large buttons. Each of them can be configured to launch an app. It might look something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/etxwo94ns9d6unds937x.png)

Each button has two actions:
* A simple tap obviously launches the configured app
* A long press opens the configuration screen

## Configuration screen
This is the place, where you can choose the apps to be displayed on each button.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/p2cvyi0vxyisxz0rkdde.png)

This screen only displays a list with the installed apps. You can now select an item from the list which will be displayed on the launcher button. In case it's necessary to launch another app, there's the play button on the right of each item, that directly launches the app.

# Technical details
To build this app, I needed a few things:
1. two screens as shown above
2. list of installed apps
3. a way to launch apps
4. some kind of persistence

As I said, there's enough information regarding no. 1, so I'm not going to talk much about building the screens. Instead, I'll show you how to tackle no. 2 and 3.

## Launching Apps from Flutter
Flutter is rather young in my eyes, but it already has a nice ecosystem. There's a lot of packages with useful features available via [pub.dev](https://pub.dev).
So if you are looking for some specific functionality, be sure to check there.

To launch apps, you can use [device_apps](https://pub.dev/packages/device_apps). device_apps offers functions to
* get a list of installed apps
* get the app icon
* launch apps

To use it, you need to add the dependency to your pubspec.yaml:
<pre>
...
  dependencies:
    device_apps: ^1.0.9
    ...
...
</pre>

Then run ```flutter pub get``` to update your dependencies and get the package. Once that is done, you can use the package inside your code.

## Get a list of installed apps
To get a list of apps, you can use getInstalledApplications.

<pre>
  import 'package:device_apps/device_apps.dart';

  ...

  _getAppList() async {
    List<Application> apps = await DeviceApps.getInstalledApplications(
      onlyAppsWithLaunchIntent: true,
      includeSystemApps: false,
      includeAppIcons: true,
    );
    return apps;
  }

  ...
</pre>

getInstalledApplications is an async function that returns a Future. You can use await to directly get the List. 
You can control the information you get from that function with the given parameters.
```
  onlyAppsWithLaunchIntent -> you'll get apps that have a launch intent
                              (which means you can start them)
  includeSystemApps        -> defines whether you'll also see system apps 
                              in the list
  includeAppIcons          -> if that is set to true, you'll also get the 
                              app icon which you can display
```
Once you have that list, it's pretty straight-forward to display a ListView containing the apps.

### Access the icon
The icon's data is stored in the icon property of the ApplicationWithIcon object. You can pass that data on to Image.memory and get an Image that can be displayed in your UI.

```
Application app = ...
Image.memory((app as ApplicationWithIcon).icon, width: 32);
```
### Launch an app
```
Application app = ...
DeviceApps.openApp(app.packageName);
```
To launch an app, device_apps uses the package name, so that would be something like 'to.dev.awesomeApp'. The Application object already has that information.
Note: this works for apps that do have a launch intent. I don't need to launch apps without launch intent, so I haven't yet figured out, what's required to do that.

## Persistence
As there is some configuration effort involved, I need some kind of persistence (who would want to configure the launcher buttons every time the launcher gets re-started?).

There are two options for that. Either store the information somewhere in a file, or store it in a database.

I used another package from pub.dev that offers access to a local SQLite database: [sqflite](https://pub.dev/packages/sqflite).
With that, you get all you need to store data in a local database.

sqflite does have a nice documentation, so I'll not go into the details. If you want to know more, you should head over to pub.dev and check their documentation and usage examples.

# That's all folks!

So, that's it, mission accomplished. "Mother" owns a Smartphone and can use it to do her favourite things without being confused by the host of options that would normally be available.

Thank you for reading, I hope you found something you can use in your own projects. And of course, if you have questions or would like to know more about some of the details, feel free to ask.

By the way: I wasn't really honest in the beginning. Of course I did write yet another Todo app and hid it in the play store just because I could...