Android Slices are a brand new way to display remote content from your application in many different places, such as Google Search (and Google Assistant in the future). We can think of them as interactive, templated views. Thanks to standardized rules how Slices can be created, they can be used across many different Android versions. Slices are part of Android Jetpack, which makes them backwards compatible back to API 19 (KitKat) - so Slices will be available almost to all users of Android devices.
The first major advantage of using Slices is navigation to your app. Whenever a user starts to search something your application is able to display content created by you. For example, imagine creating a complex weather application. How cool will it be if you can display current weather in user’s location just after he finishes typing ‘weather’ in Google Search? With Android Slices user doesn’t have to launch your app to use it - your app content will be presented to the user as one of the search results. What is more, the user can jump right to your application just by tapping on the search result.
Interactive actions are the next major feature of Android Slices. Thanks to it, a user can take action immediately in your app just by clicking on Slice. Imagine a bank application which has a blocking credit card feature. The user knows it can be done, but first, launching the app and navigating to proper screen needs to be performed in order to block credit card. With Android Slices, the only thing user needs to do is just to type “card” in Google Search - one of the results will be “Block Card”. Of course, after clicking on it, proper action will be executed right in your application.
You can use Slices to deliver your content when a
To be able to implement your own Slice you will need:
The first thing we need to do is create SliceProvider which will be responsible for delivering our Slices to other applications. We can create it from the template (if we are using Android Studio 3.2+) by right-clicking on the application package and choosing New -> Other -> SliceProvider. IDE will create all the boilerplate code for us including Gradle dependencies and modifying AndroidManifest.xml file.
Tip: If you are using Kotlin, its worth to use slice-builders-ktx
As you see, the whole process has generated many lines of code. For now, we don’t need to go through all of the methods - we are interested only in one of them.
onBindSlice(Uri) is the most important method of SliceProvider. Its responsible for creating Slice from desired URI. If some application
override fun onBindSlice(sliceUri: Uri): Slice? {
val context = context ?: return null
return if (sliceUri.path == "/hello-world") {
list(context, sliceUri, ListBuilder.INFINITY) {
row {
title = "Hello world!"
primaryAction = createActivityAction()
}
}
} else null
}
That wasn’t hard - we created our first Slice very easily. But what we should do to be able to see our work? We need an application which can display Slices.
adb shell am start -a android.intent.action.VIEW -d slice-<uri>
Where URI is for example: content://com.example.slices/hello-world
It is a standard command for starting intent with data. After executing it, SliceViewer should launch and present your slice for you:
Of course, simple Hello World is not all you can do with Slices. Basically, we can divide them into three categories:
That's the easiest and less complex Slice type. It’s used to present some kind of static data, as we have done it in ’Our first Slice’ paragraph. It can contain more data, rows or images but those are always static and its purpose is to present content for a user and redirect him to your app.
This kind of slices is made for handling user input. We define actions which will be executed by our application. We can use built-in support for sliders and toggles to create engaging actions our user can perform.
We are using dynamic slices for displaying content highly bounded with our application. This kind of slices can fetch data from the application, modify app content or perform rich in-app actions.
As I said before, Slices are templated. That means we can use only predefined builders and not our custom views. The root of every Slice is ListBuilder, and as you remember we used it in our first Slice. We can add to it various types of items like rows, headers, actions and input widgets. It gives us the opportunity to create rich and complex Slices using very clean API. Our ListBuilder can contain:
For detailed information about how to use those components, you can visit official Android documentation where each element is explained. Below you can see the code which combines some types of supported builders:
return list(context, uri, ListBuilder.INFINITY) {
row {
title = "Warsaw"
subtitle = "19°C, Sunny"
primaryAction = createGenericAction(R.drawable.ic_wb_sunny_black_24dp, "Open App Action")
setTitleItem(
IconCompat.createWithResource(context, R.drawable.ic_wb_sunny_black_24dp).apply {
setTint(Color.parseColor("#F8F523"))
}, ListBuilder.SMALL_IMAGE
)
}
gridRow {
cell {
addImage(IconCompat.createWithResource(context, R.drawable.ic_wb_cloudy_black_24dp), ListBuilder.SMALL_IMAGE)
addTitleText("Monday")
addText("15°C, Cloudy")
}
cell {
addImage(IconCompat.createWithResource(context, R.drawable.ic_wb_sunny_black_24dp), ListBuilder.SMALL_IMAGE)
addTitleText("Tuesday")
addText("16°C, Sunny")
}
cell {
addImage(IconCompat.createWithResource(context, R.drawable.ic_wb_cloudy_black_24dp), ListBuilder.SMALL_IMAGE)
addTitleText("Wednesday")
addText("18°C, Cloudy")
}
}
setSeeMoreAction(PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), 0))
}
}
Here is how our Slice looks like:
Slices can be presented in three sizes. How they will be displayed depends on how much space is left on the screen. To be sure our Slice will be displayed properly we should test it across different Slice modes and know how they behave:
They are restricted by height, so only first of our rows will be displayed with all actions and content in it.
Large Slices will contain all the rows you created if scrolling is enabled or as many items as it can fit.
When our Slice is presented as a shortcut only our first row (or header) primary action will be displayed as an icon.
Thanks to SliceViewer we can easily test if our Slice is displayed properly in each mode - we have to change mode in SliceViewer application toolbar:
Let's see how our previous example will look in those modes:
Now we can be sure our Slices will be displayed properly on any kind of Android device!
Please remember that SliceBuilders API for Kotlin (slice-builders-
In next part of our Android Slices Introduction we will take a closer look on the building Interactive and Dynamic Slices. Stay tuned!
If you want to see the whole code used in this article, check out this GitHub repository:
https://github.com/GabrielSamojlo/android-slices/tree/introduction
Happy coding!