How to develop Slices apps

How to develop Slices apps

Transcript

  1. 3.
  2. 4.
  3. 18.

    Gradle buildscript { repositories { google() } dependencies { classpath

    'com.android.tools.build:gradle:3.2.0-alpha15' } } // ... dependencies { implementation 'androidx.slice:slice-core:1.0.0-alpha1' implementation ‘androidx.slice:slice-builders:1.0.0-alpha1' // ssIf you wanna use SliceView implementation 'androidx.slice:slice-view:1.0.0-alpha1' }
  4. 19.

    AndroidManifest.xml <application ... <provider android:name=".MySliceProvider" android:authorities="jp.wasabeef.slices" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW"

    /> <category android:name="android.app.slice.category.SLICE" /> </intent-filter> </provider> <activity android:name=".MainActivity"> ... </activity> </application>
  5. 20.

    AndroidManifest.xml <application ... <provider android:name=".MySliceProvider" android:authorities="jp.wasabeef.slices" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW"

    /> <category android:name="android.app.slice.category.SLICE" /> </intent-filter> </provider> <activity android:name=".MainActivity"> ... </activity> </application>
  6. 21.

    AndroidManifest.xml <application ... <provider android:name=".MySliceProvider" android:authorities="jp.wasabeef.slices" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW"

    /> <category android:name="android.app.slice.category.SLICE" /> </intent-filter> </provider> <activity android:name=".MainActivity"> ... </activity> </application>
  7. 22.

    AndroidManifest.xml <application ... <provider android:name=".MySliceProvider" android:authorities="jp.wasabeef.slices" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW"

    /> <category android:name="android.app.slice.category.SLICE" /> </intent-filter> </provider> <activity android:name=".MainActivity"> ... </activity> </application>
  8. 23.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  9. 24.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  10. 25.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  11. 26.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { /** content://jp.wasabeef.slices/ping **/ } "/open" -> { /** content://jp.wasabeef.slices/open **/ } "/map" -> { /** content://jp.wasabeef.slices/map **/ } "/dog" -> { /** content://jp.wasabeef.slices/dog **/ } "/cat" -> { /** content://jp.wasabeef.slices/cat **/ } else -> null } } }
  12. 27.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  13. 28.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  14. 29.

    SliceProvider class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  15. 31.

    Basic Sample OK $ adb shell am start -a android.intent.action.VIEW

    \ -d slice-content://jp.wasabeef.slices/ping NG $ adb shell am start -a android.intent.action.VIEW \ -d slice-content://jp.wasabeef.slices/hoge
  16. 32.

    SliceAction override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path)

    { "/open" -> createOpenActivity(sliceUri) else -> null } } private fun createOpenActivity(sliceUri: Uri): Slice { return ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.apply { setTitle("Perform action in app") setPrimaryAction(createActivityAction()) } }.build() } private fun createActivityAction(): SliceAction { val intent = Intent(context, MainActivity::class.java) return SliceAction(PendingIntent.getActivity(context, 0, intent, 0), IconCompat.createWithResource(context, R.mipmap.ic_launcher), "Open MainActivity.") }
  17. 33.

    SliceAction override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path)

    { "/open" -> createOpenActivity(sliceUri) else -> null } } private fun createOpenActivity(sliceUri: Uri): Slice { return ListBuilder(context, sliceUri, ListBuilder.INFINITY) .addRow { it.apply { setTitle("Perform action in app") setPrimaryAction(createActivityAction()) } }.build() } private fun createActivityAction(): SliceAction { val intent = Intent(context, MainActivity::class.java) return SliceAction(PendingIntent.getActivity(context, 0, intent, 0), IconCompat.createWithResource(context, R.mipmap.ic_launcher), "Open MainActivity.") }
  18. 34.

    SliceAction package androidx.slice.core; ... /** * Interface for a slice

    action, supports tappable icons, custom toggle icons, * and default toggles. */ public interface SliceAction { @Nullable SliceAction setContentDescription(@NonNull CharSequence description); SliceAction setChecked(boolean isChecked); SliceAction setPriority(@IntRange(from = 0) int priority); @Nullable PendingIntent getAction(); @Nullable IconCompat getIcon(); @Nullable CharSequence getTitle(); @Nullable CharSequence getContentDescription(); int getPriority(); boolean isToggle(); boolean isChecked(); @SliceHints.ImageMode int getImageMode(); boolean isDefaultToggle(); }
  19. 35.

    SliceAction /** * Construct a SliceAction representing a tappable icon.

    * * @param action the pending intent to invoke for this action. * @param actionIcon the icon to display for this action. * @param actionTitle the title for this action, also used for content description * if one hasn't * been set via {@link #setContentDescription(CharSequence)}. */ public SliceAction(@NonNull PendingIntent action, @NonNull IconCompat actionIcon, @NonNull CharSequence actionTitle) { this(action, actionIcon, ICON_IMAGE, actionTitle); }
  20. 36.

    Primary Action Sample http://www.meg-snow.com/products/ $ adb shell am start -a

    android.intent.action.VIEW \ -d slice-content://jp.wasabeef.slices/open
  21. 37.

    GridRow class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } } http://www.meg-snow.com/products/
  22. 38.

    GridRow class MySliceProvider : SliceProvider() { override fun onCreateSliceProvider(): Boolean

    = true override fun onBindSlice(sliceUri: Uri): Slice? { return when (sliceUri.path) { "/ping" -> { ListBuilder(context, sliceUri, INFINITY) .addRow { it.setTitle("pong") } .build() } else -> null } } }
  23. 39.

    GridRow return ListBuilder(context, sliceUri, INFINITY) .addGridRow { it.apply { addCell

    { // title, image, intent …etc } addCell { // title, image, intent …etc } addCell { // title, image, intent …etc } } }.build() http://www.meg-snow.com/products/
  24. 42.

    SliceView http://www.meg-snow.com/products/ http://www.meg-snow.com/products/ val sliceUri = Uri.parse("content://jp.wasabeef.slices/open") // Sync val

    manager = SliceManager.getInstance(context!!) sliceView.slice = manager.bindSlice(sliceUri) // Async and LiveData SliceLiveData.fromUri(context, sliceUri) .observe(this, Observer({ sliceResult -> sliceView.slice = sliceResult }))