Not many know about it, and Google rarely advertises it, but the Android operating system has had a theming framework built into it for a few years now. It's called the Runtime Resource Overlay framework, RRO for short, and it dramatically reduces the effort needed to create custom themes for your phone.
With RRO, you can quickly create themes that can change the look and feel of almost every app that's installed on an Android device. Because Android's system user interface components, including the navigation bar, the status bar, the notifications tray, and the quick settings tray, themselves belong to an app, you can change their looks too. And the best part about it is that you don't have to write any Java code whatsoever.
What's the catch, you ask? Well, the framework can be used only by privileged apps. More specifically, by apps that are installed in a location that can be accessed only by the root user, or by someone who's creating a custom ROM.
In this quick tip, I'll be showing you how to use the framework to create a simple theme that changes the looks of the quick settings tray.
To be able to follow along, you'll need the following:
- an Android emulator running Android Marshmallow or higher
- the latest version of the Android SDK
If you've never used the Android SDK from the command line and are not familiar with Android firmware, reading the following tutorials would be a good idea:
- AndroidHow to Dissect an Android ApplicationAshraff Hathibelagal
- AndroidAn Introduction to Android FirmwareAshraff Hathibelagal
What Does RRO Really Do?
Although an Android app's business logic is written in Java or Kotlin, its user interface is primarily created using XML files. A well-written Android app will have separate XML resources that define its layouts, colors, strings, and attributes. The RRO framework, as its name suggests, lets you overlay those XML resources with your own custom XML resources. It's not limited to just XML resources, though. It also allows you to change an app's drawables and fonts.
An app that uses the RRO framework usually doesn't contain any Java code. It is composed only of XML files and, if necessary, fonts and images. Nevertheless, like all Android apps, it must be a valid and signed APK.
1. Create a New Project
We won't need Android Studio to create a project that uses the RRO framework. For now, all you need is a new project directory and an AndroidManifest.xml file. You are free to create them either with a file explorer or a terminal.
mkdir MyOverlays && cd MyOverlays touch AndroidManifest.xml
The manifest file must contain the package name of your application, and the package name of the application that you are creating overlays for. Because we want to change the looks of the quick settings tray today, we must use
com.android.systemui as the target package name.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android" package="com.tutsplus.myoverlays"> <overlay android:targetPackage="com.android.systemui" android:priority="1"/> </manifest>
At this point, we are ready to start theming the quick settings tray—and any other components of the Android system UI.
2. Create a Theme
To overlay a resource of the target application, your application must have a resource with the same name. For example, if you want to change the colors of the target application, you will usually have to overlay its colors.xml file with your own colors.xml file.
To make things easy for you, the RRO framework doesn't expect the overlay to be comprehensive and capable of handling all the details present in the original resource. In other words, your overlay needs to have only those details that you want to change.
To make things clearer, let's say we want to change the background color of the quick settings tray from the default blue-grey to a deep orange. The value of the color is specified in the res/values/colors.xml file of the system UI app. If you are curious about its contents, you can take a look at the file on the official Android Git repository.
To change the color, you must now create a res/values/colors.xml file in your project.
mkdir -p res/values touch res/values/colors.xml
Inside the colors.xml file, to change the background color of the tray, we must target a color named
system_primary_color. Therefore, add the following XML to the file:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="system_primary_color">#FFBF360C</color> <!-- deep orange 900 --> </resources>
It's worth noting that the above XML is no different from the XML you'd use while creating normal apps with Android Studio.
Our simple theme is ready! If you want to, you can add more
<color> tags to the file to change other colors of the system UI.
3. Generate an APK
We'll now be using the Android Asset Packaging Tool,
aapt for short, which is a part of the Android SDK, to convert our simple project into an APK file that can be used by the Android platform.
To generate the APK, you must simply point
aapt to the manifest file, the res directory, and the target platform's android.jar file. Of course, you must also specify the name you want to give to the APK file.
aapt package -M AndroidManifest.xml -S res/ \ -I ~/Android/Sdk/platforms/android-23/android.jar \ -F myoverlays.apk.u
In the above command, you can see that I've chosen to name the APK file myoverlays.apk.u. That's because our APK is currently both unsigned and unaligned.
To sign it, you must use the
jarsigner tool. For now, I suggest you sign it with the default Android debug keystore.
jarsigner -keystore ~/.android/debug.keystore \ myoverlays.apk.u androiddebugkey
Finally, you must align—and thus optimize—the APK using the
zipalign tool. As inputs, the tool expects the names of the unaligned and aligned APKs, along with a number that specifies the alignment boundaries. As of 2017, the number can be nothing else but
zipalign 4 myoverlays.apk.u myoverlays.apk
4. Install the APK
To install an APK that uses the RRO framework, you must simply place it inside the /system/vendor/overlay directory. The directory, by default, belongs to a read-only filesystem and is only accessible to the root user. If you are a custom ROM developer, or have rooted your Android device, you should have no trouble installing the APK.
In this quick tip, however, I'll be showing you how to install the APK on an emulator. This way, you can test the overlay without jeopardizing your phone.
Start by firing up an emulator in the writable filesystem mode using the
emulator command-line tool.
emulator -avd Nexus_5X_API_23 -writable-system
You can now use the
adb tool to gain root privileges on the emulator, if you don't have them already.
Next, remount the /system filesystem as writeable, again using
The /system/vendor/overlay directory doesn't exist on the emulator. You must create it manually yourself. The easiest way to do so is by starting a shell on the emulator.
adb shell mkdir -p /system/vendor/overlay exit
Finally, push the APK to the directory using
adb push myoverlays.apk /system/vendor/overlay
Wait for a few seconds for Android to detect and install the APK, and then restart the emulator for the theme to take effect.
After the restart, if you pull down the quick settings tray, you should be able to see the theme in action.
In this quick tip, you learned how to use the Runtime Resource Overlay framework to create themes for Android. Although the theme we created was extremely simple, you can apply the skills you gained today to create far more complex themes. For example, you can overlay the strings.xml file to change the labels of the UI elements an app displays. Similarly, you can overlay the dimens.xml file to change the sizes of an app's UI elements.
Documentation about the RRO framework is very scarce. Nonetheless, there's a lot you can learn about it by poring over the Android platform's source code.
While you're here, check out some of our other posts on Android development!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.Update me weekly
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!Translate this post