<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: smuschel</title>
    <description>The latest articles on Forem by smuschel (@smuschel).</description>
    <link>https://forem.com/smuschel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F108344%2F86fae060-5a80-441c-a7b9-fd927617e93a.png</url>
      <title>Forem: smuschel</title>
      <link>https://forem.com/smuschel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/smuschel"/>
    <language>en</language>
    <item>
      <title>Writing a custom Android launcher using Flutter</title>
      <dc:creator>smuschel</dc:creator>
      <pubDate>Thu, 30 Jan 2020 17:50:38 +0000</pubDate>
      <link>https://forem.com/smuschel/writing-a-custom-android-launcher-using-flutter-oca</link>
      <guid>https://forem.com/smuschel/writing-a-custom-android-launcher-using-flutter-oca</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;
  
  
  So - what's in this post?
&lt;/h1&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;h1&gt;
  
  
  Now how does this work?
&lt;/h1&gt;

&lt;p&gt;To make things short, I found the necessary information in this reddit: &lt;a href="https://www.reddit.com/r/Flutter/comments/bkknj9/android_launcher_in_flutter/" rel="noopener noreferrer"&gt;Android Launcher in Flutter&lt;/a&gt;&lt;br&gt;
So all credit goes to the person who answered that question.&lt;/p&gt;

&lt;p&gt;For your app to become a launcher, you'll just need to add these two categories to your activity in AndroidManifest.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;category android:name="android.intent.category.HOME" /&amp;gt;
&amp;lt;category android:name="android.intent.category.DEFAULT" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's really all there is to it.&lt;/p&gt;

&lt;p&gt;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...&lt;/p&gt;

&lt;h1&gt;
  
  
  The launcher
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;My second motivation was to try things and find out, how Flutter works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Home screen
&lt;/h2&gt;

&lt;p&gt;The home screen needs to be dead simple. There are four apps, my "users" are typically going to need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dialer&lt;/li&gt;
&lt;li&gt;Text messages&lt;/li&gt;
&lt;li&gt;Camera&lt;/li&gt;
&lt;li&gt;Favourite messenger&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fetxwo94ns9d6unds937x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fetxwo94ns9d6unds937x.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each button has two actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A simple tap obviously launches the configured app&lt;/li&gt;
&lt;li&gt;A long press opens the configuration screen&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration screen
&lt;/h2&gt;

&lt;p&gt;This is the place, where you can choose the apps to be displayed on each button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp2cvyi0vxyisxz0rkdde.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp2cvyi0vxyisxz0rkdde.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;
  
  
  Technical details
&lt;/h1&gt;

&lt;p&gt;To build this app, I needed a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;two screens as shown above&lt;/li&gt;
&lt;li&gt;list of installed apps&lt;/li&gt;
&lt;li&gt;a way to launch apps&lt;/li&gt;
&lt;li&gt;some kind of persistence&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launching Apps from Flutter
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://pub.dev" rel="noopener noreferrer"&gt;pub.dev&lt;/a&gt;.&lt;br&gt;
So if you are looking for some specific functionality, be sure to check there.&lt;/p&gt;

&lt;p&gt;To launch apps, you can use &lt;a href="https://pub.dev/packages/device_apps" rel="noopener noreferrer"&gt;device_apps&lt;/a&gt;. device_apps offers functions to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get a list of installed apps&lt;/li&gt;
&lt;li&gt;get the app icon&lt;/li&gt;
&lt;li&gt;launch apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use it, you need to add the dependency to your pubspec.yaml:&lt;/p&gt;

&lt;pre&gt;
...
  dependencies:
    device_apps: ^1.0.9
    ...
...
&lt;/pre&gt;

&lt;p&gt;Then run&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;flutter pub get&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 to update your dependencies and get the package. Once that is done, you can use the package inside your code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get a list of installed apps
&lt;/h2&gt;

&lt;p&gt;To get a list of apps, you can use getInstalledApplications.&lt;/p&gt;

&lt;pre&gt;
  import 'package:device_apps/device_apps.dart';

  ...

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

  ...
&lt;/pre&gt;

&lt;p&gt;getInstalledApplications is an async function that returns a Future. You can use await to directly get the List. &lt;br&gt;
You can control the information you get from that function with the given parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  onlyAppsWithLaunchIntent -&amp;gt; you'll get apps that have a launch intent
                              (which means you can start them)
  includeSystemApps        -&amp;gt; defines whether you'll also see system apps 
                              in the list
  includeAppIcons          -&amp;gt; if that is set to true, you'll also get the 
                              app icon which you can display
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have that list, it's pretty straight-forward to display a ListView containing the apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access the icon
&lt;/h3&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application app = ...
Image.memory((app as ApplicationWithIcon).icon, width: 32);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Launch an app
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application app = ...
DeviceApps.openApp(app.packageName);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;br&gt;
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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistence
&lt;/h2&gt;

&lt;p&gt;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?).&lt;/p&gt;

&lt;p&gt;There are two options for that. Either store the information somewhere in a file, or store it in a database.&lt;/p&gt;

&lt;p&gt;I used another package from pub.dev that offers access to a local SQLite database: &lt;a href="https://pub.dev/packages/sqflite" rel="noopener noreferrer"&gt;sqflite&lt;/a&gt;.&lt;br&gt;
With that, you get all you need to store data in a local database.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;
  
  
  That's all folks!
&lt;/h1&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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...&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>android</category>
    </item>
  </channel>
</rss>
