Slices provide the ability for your app to share information and controls with other apps. In my previous post, Share a Slice of Your App, I covered the basics of Slices on Android. Introduced in Android Pie (API 28), they are packaged as a library and work all the way back to Android KitKat (API 19). If you haven't already, give it a read through to learn about the main concepts in Slices, how to create a simple one, and how to view them on your devices. Before continuing with this post, make sure you have a SliceProvider in place to build off of for the interactive slices.
In my previous post, I covered adding multiple actions to your Slice to make it more interactive. In this post, I'll show how to add a toggle action. This type of action is good for controls the user can enable or disable in your application. This type of control also requires you to create a component to handle the data in your app. Read on to find out more!
For toggle actions, you will need to create either a Service
or a BroadcastReceiver
to handle
the updates. The Intent
object that these components receive will contain extra data indicating
if the toggle is enabled or not. You can handle the action appropriately there. For this example
I'll use a Service
to handle the updates.
For now my Service
will be very plain. I'll fill out the actual implementation once I finish my
Slice. This will just act as a placeholder so I can create a valid PendingIntent
.
https://gist.github.com/557de13108e17ad7edb9443521b5d756
Don't forget to register your service in your AndroidManifest.xml
so the system can start it
correctly.
The next step is to create a path for your toggle Slice. To continue with my creative streak, I'll
call this path /toggle
.
https://gist.github.com/596433359499b0dd19ab8d898669fa9d
To create my toggle action I can use the createToggle()
static method on the SliceAction
class.
This method needs a PendingIntent
, a title, and a boolean flag indicating if the toggle is
checked.
https://gist.github.com/b47c38cadb9d293871b722f27b288ef1
The FocusManager
is just an object responsible for determining the current state of my toggle.
The data is stored in a property that can be returned quickly back to my SliceProvider
.
https://gist.github.com/325b82e887e9cea1f6d9b4aa5efaca3d
Returning this value quickly is important so there isn't a delay when your Slice is being
displayed. In fact, if you take too long to return the information, an exception is thrown, and your
Slice will not be shown. Even reading from SharedPreferences
is too long in this case. If reading
your data takes too long, you will need to initialize your Slice with placeholder data while you
query the real data in the background. Once you have the data, you can notify your SliceProvider
that the data has changed and it will rebind accordingly.
Once I have my toggle action, I can create the rest of the data for my Slice. I'll change the text of my Slice based on my toggle state. If my user is not focusing, I will prompt them to start, and if they are focusing, I'll prompt them to turn it off when they are done.
https://gist.github.com/d3402471c18628a3a2274fbbeeea1bca
With my action, title, and subtitle ready, I can move on to creating my Slice. I can add my toggle action as my only action so the user can see it and interact with it.
https://gist.github.com/8b1a5ca312f65f1db717085c4cf17c64
The last step is to fill out my FocusService
to handle the toggle changes. I can pull out the
extra data from the intent and set it on my FocusManager
. I will also notify the system that the
content for my Slice URI has changed so that they system can tell my SliceProvider
to rebind my
Slice with the updated data.
https://gist.github.com/6396884a525c306c0ed853f65eac1656
With this in place, I can run my Slice and see the content change when I enable and disable the toggle.
Toggle actions provide an easy way for users to enable or disable specific functionality in your
app in an easy to find place. You can either use a Service
or a BroadcastReceiver
to handle
the user's input. Just configure a PendingIntent
for your component and the system will start it
when the data changes.
In the next post, I'll cover how to add a range action to your Slice. This allows users to provide a value from a discrete set of options.
I hope you enjoyed the post. If you have any questions please feel free to comment below. Thanks for reading!