Exploring Android Slices - JetPack
Introduction:
Slices are a new way of embedding our app's content in other surfaces, like Google Search and later in other places like Google Assistant. Slices are UI templates, which gives look and feel at home in whatever surface, they get hosts in. Also they are rich, interactive and dynamically updatable.
Before jumping into that, first migrate your project to AndroidX, (Android Studio 3.2 & above), by navigating as,
Refactor --> Migrate to AndroidX
Setup:
build.gradle
implementation 'androidx.slice:slice-core:1.0.0' implementation 'androidx.slice:slice-builders-ktx:1.0.0-alpha6' implementation 'androidx.slice:slice-builders:1.0.0'
Creating Slice Provider:
Slice Provider is a component that let us display the slices we are creating, on outside our application. We can create the Slice Provider by navigating,
File -> New -> Other -> Slice Provider
A new Slice Provider Class got created. It have automatically generated code, that provides an overview. Also it will add a block of code in AndroidManifest as below.
AndroidManifest.xml
<provider
android:name=".slices.MySliceProvider"
android:authorities="com.yamikrish.app.sliceapp"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.app.slice.category.SLICE" />
<data
android:host="app.yamikrish.com"
android:pathPrefix="/"
android:scheme="http" />
</intent-filter>
</provider>
Things to know:
Two things are more important to create the slices.(i) Slice Content
(ii) Slice Action
(i) Slice Content:
Slice content is nothing, but UI of your slice. It can be dynamic and interactive with flexible UI.
(ii) Slice Action:
SliceAction consists of a label and PendingIntent and it may be IconButton or ToggleButton (default/custom).
MySliceProvider.kt
Lets create a simple slice, that have only title and subtitle.
package com.yamikrish.app.sliceapp.slices import android.content.ContentResolver import android.content.Intent import android.net.Uri import androidx.slice.Slice import androidx.slice.SliceProvider import androidx.core.graphics.drawable.IconCompat import android.app.PendingIntent import androidx.slice.builders.* import androidx.slice.builders.ListBuilder.LARGE_IMAGE import com.yamikrish.app.sliceapp.MainActivity import com.yamikrish.app.sliceapp.R class MySliceProvider : SliceProvider() { /** * Instantiate any required objects. Return true if the provider was successfully created, * false otherwise. */ override fun onCreateSliceProvider(): Boolean { return true } /** * Converts URL to content URI (i.e. content://com.yamikrish.app.sliceapp...) */ override fun onMapIntentToUri(intent: Intent?): Uri { // Note: implementing this is only required if you plan on catching URL requests. // This is an example solution. var uriBuilder: Uri.Builder = Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) if (intent == null) return uriBuilder.build() val data = intent.data if (data != null && data.path != null) { val path = data.path.replace("/", "") uriBuilder = uriBuilder.path(path) } val context = context if (context != null) { uriBuilder = uriBuilder.authority(context.packageName) } return uriBuilder.build() } /** * Construct the Slice and bind data if available. */ override fun onBindSlice(sliceUri: Uri): Slice? { // Note: you should switch your build.gradle dependency to // slice-builders-ktx for a nicer interface in Kotlin. val path = sliceUri.getPath(); when (path) { "/mainActivity" -> return createSlice(sliceUri) } return null } fun createSlice(sliceUri: Uri): Slice { val activityAction = createActivityAction() //Create the ListBuilder - Normal Title & SubTitle// return list(context!!, sliceUri, ListBuilder.INFINITY) { row { title = "Test Launch!" subtitle = "Let's see how it works.. Just Click on it to proceed!!" primaryAction = activityAction } } } fun createActivityAction(): SliceAction { return SliceAction.create( PendingIntent.getActivity( context, 0, Intent(context, MainActivity::class.java), 0 ), IconCompat.createWithResource(context, R.drawable.ic_launcher_foreground), ListBuilder.ICON_IMAGE, "Open App" ) } /** * Slice has been pinned to external process. Subscribe to data source if necessary. */ override fun onSlicePinned(sliceUri: Uri?) { // When data is received, call context.contentResolver.notifyChange(sliceUri, null) to // trigger MySliceProvider#onBindSlice(Uri) again. } /** * Unsubscribe from data source if necessary. */ override fun onSliceUnpinned(sliceUri: Uri?) { // Remove any observers if necessary to avoid memory leaks. } }
(ii) With Image
package com.yamikrish.app.sliceapp.slices import android.content.ContentResolver import android.content.Intent import android.net.Uri import androidx.slice.Slice import androidx.slice.SliceProvider import androidx.core.graphics.drawable.IconCompat import android.app.PendingIntent import androidx.slice.builders.* import androidx.slice.builders.ListBuilder.LARGE_IMAGE import com.yamikrish.app.sliceapp.MainActivity import com.yamikrish.app.sliceapp.R class MySliceProvider : SliceProvider() { /** * Instantiate any required objects. Return true if the provider was successfully created, * false otherwise. */ override fun onCreateSliceProvider(): Boolean { return true } /** * Converts URL to content URI (i.e. content://com.yamikrish.app.sliceapp...) */ override fun onMapIntentToUri(intent: Intent?): Uri { // Note: implementing this is only required if you plan on catching URL requests. // This is an example solution. var uriBuilder: Uri.Builder = Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) if (intent == null) return uriBuilder.build() val data = intent.data if (data != null && data.path != null) { val path = data.path.replace("/", "") uriBuilder = uriBuilder.path(path) } val context = context if (context != null) { uriBuilder = uriBuilder.authority(context.packageName) } return uriBuilder.build() } /** * Construct the Slice and bind data if available. */ override fun onBindSlice(sliceUri: Uri): Slice? { // Note: you should switch your build.gradle dependency to // slice-builders-ktx for a nicer interface in Kotlin. val path = sliceUri.getPath(); when (path) { //Define the slice’s URI; I’m using ‘mainActivity’// "/mainActivity" -> return createSlice(sliceUri) } return null } fun createSlice(sliceUri: Uri): Slice { val activityAction = createActivityAction() //Create the ListBuilder - With Header and Image// return list(context!!, sliceUri, ListBuilder.INFINITY) { header { title = "Wanna Ride???" } gridRow { cell { addImage(IconCompat.createWithResource(context, R.drawable.car), LARGE_IMAGE) } } row { title = "BOOK NOW" primaryAction = activityAction } } } fun createActivityAction(): SliceAction { return SliceAction.create( PendingIntent.getActivity( context, 0, Intent(context, MainActivity::class.java), 0 ), IconCompat.createWithResource(context, R.drawable.ic_launcher_foreground), ListBuilder.ICON_IMAGE, "Open App" ) } /** * Slice has been pinned to external process. Subscribe to data source if necessary. */ override fun onSlicePinned(sliceUri: Uri?) { // When data is received, call context.contentResolver.notifyChange(sliceUri, null) to // trigger MySliceProvider#onBindSlice(Uri) again. } /** * Unsubscribe from data source if necessary. */ override fun onSliceUnpinned(sliceUri: Uri?) { // Remove any observers if necessary to avoid memory leaks. } }
Test your slices:
To test your slices, you can install apk from the below site:
https://github.com/googlesamples/android-SliceViewer/releases
You can view the full project in GitHub, here.
This comment has been removed by the author.
ReplyDeleteThank you for sharing this informative post... Keep posting! Anyone interested in android app development for your business, contact us: +919500788278
ReplyDeleteandroid development company</a
ReplyDeleteI am really impressed with your blog article, such great & useful knowledge you mentioned here! Anyone interested build Kotlin app development for your business. let me help you. We at CodersNews provide 5 Best Ranked Kotlin Mobile App Development Companies which deliver feature-rich, simple yet sophisticated, and powerful applications across globe.
ReplyDeleteYour blog on reading is so full of great insights. I love your idea of adapting trade books. We have some that have far too much text, that would be fabulous, modified for our seven-year-old reader.
ReplyDeleteTop IT Service in India
Nice article. Thank you for sharing such informative blog.
ReplyDeleteVisit Mobibiz a leading mobile app development company in Gurgaon offers mobile and web development services for its regional and global clients. We deliver scalable and robust mobility solutions for all business segments.
Thanks for sharing this informative article on Exploring Android Slices - JetPack. If you want to Kotlin app development company for your project. Please visit us.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteAre you an expert in remote front-end development with a love for readable, well-written code? Come work with us on state-of-the-art online apps while taking advantage of remote work's flexibility.
ReplyDeletehire remote web developer
Nice article. Great & useful knowledge you mentioned here! please keep sharing.
ReplyDeleteSpeaking of mobile app development, Maven Technology truly stands out as the Best Mobile App Development Company in Delhi. Our skilled developers, user-friendly designs, and commitment to quality make them the perfect choice.
Call a technical App developer today at : +91 8851223376 , +13145144152 for detailed discussions.