DEV Community

smuschel
smuschel

Posted on

Writing a custom Android launcher using Flutter

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
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" />
Enter fullscreen mode Exit fullscreen mode

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

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

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.
So if you are looking for some specific functionality, be sure to check there.

To launch apps, you can use 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:

...
  dependencies:
    device_apps: ^1.0.9
    ...
...

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.

  import 'package:device_apps/device_apps.dart';

  ...

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

  ...

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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

Launch an app

Application app = ...
DeviceApps.openApp(app.packageName);
Enter fullscreen mode Exit fullscreen mode

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.
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...

Top comments (5)

Collapse
 
anujrathore131 profile image
anujrathore131

hello, can you share apk for it?

Collapse
 
anujrathore131 profile image
anujrathore131

nevermind, got it.

Collapse
 
j0nghee profile image
Francesco Gionghi

Thanks for the post! Could you upload your code on github please? Thank you.

Collapse
 
smuschel profile image
smuschel

I pushed the project to Github: github.com/smuschel/granny
It's not the full version, as I lost that due to a hardware failure and bad backup strategy - but the launcher should work, only misses the database part. Let me know, if you have questions...

Collapse
 
janam007 profile image
Janam007

i have edited the manifest but could not get bottom snack bar to select the launcher the main directly opens up... its not working please help