Halaman ini menunjukkan cara menyiapkan lingkungan dan membuat Slice di aplikasi Anda.
Catatan: Android Studio 3.2 atau yang lebih tinggi berisi fitur dan fungsi tambahan yang dapat membantu Anda dalam pengembangan Slice:
- Alat pemfaktoran ulang AndroidX: diperlukan jika Anda bekerja dalam project yang menggunakan library AndroidX.
- Pemeriksaan lint Slice: mengenali anti-praktik umum saat membuat Slice
SliceProvider
template: menangani boilerplate saat membuatSliceProvider
Mendownload dan menginstal Slice Viewer
Download contoh terbaru
rilis APK Slice Viewer
yang dapat Anda gunakan untuk menguji Slice Anda tanpa mengimplementasikan
SliceView
API.
Jika ADB tidak disiapkan dengan benar di lingkungan Anda, lihat panduan ADB untuk informasi selengkapnya.
Instal Slice Viewer di perangkat Anda dengan menjalankan perintah berikut dalam
direktori yang sama seperti slice-viewer.apk
yang didownload:
adb install -r -t slice-viewer.apk
Menjalankan Slice Viewer
Anda dapat meluncurkan Slice Viewer dari project Android Studio atau command line:
Meluncurkan Slice Viewer dari project Android Studio Anda
- Dalam project Anda, pilih Jalankan > Edit Konfigurasi ...
- Di sudut kiri atas, klik tanda plus berwarna hijau
Pilih Aplikasi Android
Masukkan slice dalam kolom nama
Pilih modul aplikasi Anda pada dropdown Modul
Pada Opsi Peluncuran, pilih URL dari dropdown Luncurkan
Masukkan
slice-<your slice URI>
dalam kolom URLContoh:
slice-content://com.example.your.sliceuri
Klik Oke.
Meluncurkan fitur Slice Viewer melalui ADB (command line)
Jalankan aplikasi Anda dari Android Studio:
adb install -t -r <yourapp>.apk
Lihat Slice Anda dengan menjalankan perintah berikut:
adb shell am start -a android.intent.action.VIEW -d slice-<your slice URI>
Slice Viewer yang menampilkan WiFi Slice tunggal
Melihat semua Slice Anda di satu tempat
Selain meluncurkan Slice tunggal, Anda dapat melihat daftar tetap Slice Anda.
- Gunakan kotak penelusuran untuk menelusuri Slice melalui URI secara manual (contohnya,
content://com.example.android.app/hello
). Setiap kali Anda menelusuri, Slice akan ditambahkan ke daftar. - Kapan pun Anda meluncurkan alat Slice Viewer dengan URI Slice, Slice akan ditambahkan ke daftar.
- Anda dapat menggeser Slice untuk menghapusnya dari daftar.
- Ketuk URI Slice untuk melihat halaman yang hanya berisi Slice tersebut. Ini memiliki efek yang sama seperti meluncurkan Slice Viewer dengan URI Slice.
Slice Viewer yang menampilkan daftar Slice
Melihat Slice dalam mode yang berbeda
Aplikasi yang menyajikan Slice dapat mengubah
SliceView#mode
pada waktu proses,
sehingga Anda harus memastikan bahwa Slice terlihat seperti yang diharapkan dalam setiap mode.
Pilih ikon menu di bagian kanan atas halaman untuk mengubah mode.
Slice viewer tunggal dengan mode yang disetel ke "kecil"
Membuat Slice pertama Anda
Untuk membuat Slice, buka project Android Studio, klik kanan paket
src
, lalu pilih Baru ... > Lainnya > Penyedia Slice. Ini akan membuat class
yang memperluas SliceProvider
, menambahkan
entri penyedia yang diperlukan ke AndroidManifest.xml
Anda, dan mengubah
build.gradle
untuk menambahkan dependensi Slice yang diperlukan.
Perubahan pada AndroidManifest.xml
ditunjukkan seperti berikut:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.app"> ... <application> ... <provider android:name="MySliceProvider" android:authorities="com.example.android.app" android:exported="true" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.app.slice.category.SLICE" /> </intent-filter> </provider> ... </application> </manifest>
Dependensi berikut ditambahkan ke build.gradle
Anda:
Kotlin
dependencies { // ... implementation "androidx.slice:slice-builders-ktx:(latest version)" // ... }
Java
dependencies { // ... implementation "androidx.slice:slice-builders:(latest version)" // ... }
Setiap Slice memiliki URI terkait. Saat ingin menampilkan Slice, permukaan akan
mengirimkan permintaan binding ke aplikasi Anda dengan URI ini. Aplikasi Anda kemudian akan menangani
permintaan ini dan secara dinamis membuat Slice melalui
metode
onBindSlice
. Kemudian, surface dapat menampilkan Slice jika sesuai.
Berikut adalah contoh metode onBindSlice
yang memeriksa jalur URI
/hello
dan menampilkan Slice Hello World:
Kotlin
override fun onBindSlice(sliceUri: Uri): Slice? { val activityAction = createActivityAction() return if (sliceUri.path == "/hello") { list(context, sliceUri, ListBuilder.INFINITY) { row { primaryAction = activityAction title = "Hello World." } } } else { list(context, sliceUri, ListBuilder.INFINITY) { row { primaryAction = activityAction title = "URI not recognized." } } } }
Java
@Override public Slice onBindSlice(Uri sliceUri) { if (getContext() == null) { return null; } SliceAction activityAction = createActivityAction(); ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY); // Create parent ListBuilder. if ("/hello".equals(sliceUri.getPath())) { listBuilder.addRow(new ListBuilder.RowBuilder() .setTitle("Hello World") .setPrimaryAction(activityAction) ); } else { listBuilder.addRow(new ListBuilder.RowBuilder() .setTitle("URI not recognized") .setPrimaryAction(activityAction) ); } return listBuilder.build(); }
Gunakan konfigurasi pengoperasian slice yang dibuat di bagian Slice Viewer
di atas, yang meneruskan URI Slice Anda (misalnya,
slice-content://com.android.example.slicesample/hello
) dari Slice Hello World
untuk melihatnya di Slice Viewer.
Slice Interaktif
Mirip dengan notifikasi, Anda dapat menangani klik dalam Slice dengan melampirkan
objek PendingIntent
yang
dipicu pada interaksi pengguna. Contoh berikut memulai
Activity
yang dapat menerima dan menangani intent
tersebut:
Kotlin
fun createSlice(sliceUri: Uri): Slice { val activityAction = createActivityAction() return list(context, sliceUri, INFINITY) { row { title = "Perform action in app" primaryAction = activityAction } } } fun createActivityAction(): SliceAction { val intent = Intent(context, MainActivity::class.java) return SliceAction.create( PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), 0), IconCompat.createWithResource(context, R.drawable.ic_home), ListBuilder.ICON_IMAGE, "Enter app" ) }
Java
public Slice createSlice(Uri sliceUri) { if (getContext() == null) { return null; } SliceAction activityAction = createActivityAction(); return new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .addRow(new ListBuilder.RowBuilder() .setTitle("Perform action in app.") .setPrimaryAction(activityAction) ).build(); } public SliceAction createActivityAction() { if (getContext() == null) { return null; } return SliceAction.create( PendingIntent.getActivity( getContext(), 0, new Intent(getContext(), MainActivity.class), 0 ), IconCompat.createWithResource(getContext(), R.drawable.ic_home), ListBuilder.ICON_IMAGE, "Enter app" ); }
Slice juga mendukung jenis input lain, seperti tombol, yang mencakup status dalam intent yang dikirim ke aplikasi.
Kotlin
fun createBrightnessSlice(sliceUri: Uri): Slice { val toggleAction = SliceAction.createToggle( createToggleIntent(), "Toggle adaptive brightness", true ) return list(context, sliceUri, ListBuilder.INFINITY) { row { title = "Adaptive brightness" subtitle = "Optimizes brightness for available light" primaryAction = toggleAction } inputRange { inputAction = (brightnessPendingIntent) max = 100 value = 45 } } } fun createToggleIntent(): PendingIntent { val intent = Intent(context, MyBroadcastReceiver::class.java) return PendingIntent.getBroadcast(context, 0, intent, 0) }
Java
public Slice createBrightnessSlice(Uri sliceUri) { if (getContext() == null) { return null; } SliceAction toggleAction = SliceAction.createToggle( createToggleIntent(), "Toggle adaptive brightness", true ); ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .addRow(new ListBuilder.RowBuilder() .setTitle("Adaptive brightness") .setSubtitle("Optimizes brightness for available light.") .setPrimaryAction(toggleAction) ).addInputRange(new ListBuilder.InputRangeBuilder() .setInputAction(brightnessPendingIntent) .setMax(100) .setValue(45) ); return listBuilder.build(); } public PendingIntent createToggleIntent() { Intent intent = new Intent(getContext(), MyBroadcastReceiver.class); return PendingIntent.getBroadcast(getContext(), 0, intent, 0); }
Penerima kemudian dapat memeriksa status yang diterima:
Kotlin
class MyBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.hasExtra(Slice.EXTRA_TOGGLE_STATE)) { Toast.makeText(context, "Toggled: " + intent.getBooleanExtra( Slice.EXTRA_TOGGLE_STATE, false), Toast.LENGTH_LONG).show() } } companion object { const val EXTRA_MESSAGE = "message" } }
Java
public class MyBroadcastReceiver extends BroadcastReceiver { public static String EXTRA_MESSAGE = "message"; @Override public void onReceive(Context context, Intent intent) { if (intent.hasExtra(EXTRA_TOGGLE_STATE)) { Toast.makeText(context, "Toggled: " + intent.getBooleanExtra( EXTRA_TOGGLE_STATE, false), Toast.LENGTH_LONG).show(); } } }
Slice Dinamis
Slice juga dapat berisi konten dinamis. Pada contoh berikut, Slice sekarang menyertakan jumlah siaran yang diterima dalam kontennya:
Kotlin
fun createDynamicSlice(sliceUri: Uri): Slice { return when (sliceUri.path) { "/count" -> { val toastAndIncrementAction = SliceAction.create( createToastAndIncrementIntent("Item clicked."), actionIcon, ListBuilder.ICON_IMAGE, "Increment." ) list(context, sliceUri, ListBuilder.INFINITY) { row { primaryAction = toastAndIncrementAction title = "Count: ${MyBroadcastReceiver.receivedCount}" subtitle = "Click me" } } } else -> { list(context, sliceUri, ListBuilder.INFINITY) { row { primaryAction = createActivityAction() title = "URI not found." } } } } }
Java
public Slice createDynamicSlice(Uri sliceUri) { if (getContext() == null || sliceUri.getPath() == null) { return null; } ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY); switch (sliceUri.getPath()) { case "/count": SliceAction toastAndIncrementAction = SliceAction.create( createToastAndIncrementIntent("Item clicked."), actionIcon, ListBuilder.ICON_IMAGE, "Increment." ); listBuilder.addRow( new ListBuilder.RowBuilder() .setPrimaryAction(toastAndIncrementAction) .setTitle("Count: " + MyBroadcastReceiver.sReceivedCount) .setSubtitle("Click me") ); break; default: listBuilder.addRow( new ListBuilder.RowBuilder() .setPrimaryAction(createActivityAction()) .setTitle("URI not found.") ); break; } return listBuilder.build(); } public PendingIntent createToastAndIncrementIntent(String s) { Intent intent = new Intent(getContext(), MyBroadcastReceiver.class) .putExtra(MyBroadcastReceiver.EXTRA_MESSAGE, s); return PendingIntent.getBroadcast(getContext(), 0, intent, 0); }
Dalam contoh ini, saat jumlah ditampilkan, data tidak diperbarui dengan sendirinya. Anda dapat
memodifikasi penerima siaran untuk memberi tahu sistem bahwa telah terjadi
perubahan menggunakan
ContentResolver#notifyChange
.
Kotlin
class MyBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.hasExtra(Slice.EXTRA_TOGGLE_STATE)) { Toast.makeText( context, "Toggled: " + intent.getBooleanExtra( Slice.EXTRA_TOGGLE_STATE, false ), Toast.LENGTH_LONG ).show() receivedCount++; context.contentResolver.notifyChange(sliceUri, null) } } companion object { var receivedCount = 0 val sliceUri = Uri.parse("content://com.android.example.slicesample/count") const val EXTRA_MESSAGE = "message" } }
Java
public class MyBroadcastReceiver extends BroadcastReceiver { public static int sReceivedCount = 0; public static String EXTRA_MESSAGE = "message"; private static Uri sliceUri = Uri.parse("content://com.android.example.slicesample/count"); @Override public void onReceive(Context context, Intent intent) { if (intent.hasExtra(EXTRA_TOGGLE_STATE)) { Toast.makeText(context, "Toggled: " + intent.getBooleanExtra( EXTRA_TOGGLE_STATE, false), Toast.LENGTH_LONG).show(); sReceivedCount++; context.getContentResolver().notifyChange(sliceUri, null); } } }
Template
Slices mendukung berbagai template. Untuk detail selengkapnya tentang opsi dan perilaku template, lihat Template.