Auf dieser Seite erfahren Sie, wie Sie Ihre Umgebung einrichten und Slices in Ihrer Anwendung erstellen.
Hinweis: Android Studio 3.2 oder höher enthält zusätzliche Tools und Funktionen für die Slice-Entwicklung:
- AndroidX-Refaktorierungstool: erforderlich, wenn Sie in einem Projekt arbeiten, das AndroidX-Bibliotheken verwendet.
- Slice-Lint-Prüfungen: Damit werden gängige Anti-Practices beim Erstellen von Slices abgefangen.
- Vorlage
SliceProvider
: bearbeitet den Textbaustein beim Erstellen einesSliceProvider
-Objekts
Slice Viewer herunterladen und installieren
Laden Sie die neueste exemplarische Slice Viewer-APK-Version herunter, mit der Sie Ihre Slices testen können, ohne die SliceView
API zu implementieren.
Wenn ADB in Ihrer Umgebung nicht richtig eingerichtet ist, finden Sie weitere Informationen in der ADB-Anleitung.
Installieren Sie die Slice Viewer auf Ihrem Gerät. Führen Sie dazu den folgenden Befehl im selben Verzeichnis wie das heruntergeladene slice-viewer.apk
aus:
adb install -r -t slice-viewer.apk
Slice-Viewer ausführen
Sie können den Slice Viewer entweder über Ihr Android Studio-Projekt oder über die Befehlszeile starten:
Slice Viewer aus Ihrem Android Studio-Projekt starten
- Wählen Sie in Ihrem Projekt Run > Edit Configurations... (Ausführen > Konfigurationen bearbeiten...) aus.
- Klicken Sie links oben auf das grüne Pluszeichen.
Wählen Sie Android-App aus.
Geben Sie slice in das Namensfeld ein.
Wählen Sie im Drop-down-Menü Module Ihr App-Modul aus.
Wählen Sie unter Launch Options (Startoptionen) im Drop-down-Menü Launch (Starten) die Option URL (URL) aus.
Geben Sie
slice-<your slice URI>
in das URL-Feld ein.Beispiel:
slice-content://com.example.your.sliceuri
Klicken Sie auf OK.
Slice Viewer über ADB (Befehlszeile) starten
Führen Sie Ihre App über Android Studio aus:
adb install -t -r <yourapp>.apk
Rufen Sie das Slice auf, indem Sie den folgenden Befehl ausführen:
adb shell am start -a android.intent.action.VIEW -d slice-<your slice URI>
Slice-Anzeige, in der ein einzelnes WLAN-Slice angezeigt wird
Alle deine Slices an einem Ort ansehen
Sie können nicht nur einen einzelnen Slice starten, sondern auch eine persistente Liste Ihrer Slices abrufen.
- Verwenden Sie die Suchleiste, um manuell über URI nach Ihren Segmenten zu suchen (z. B.
content://com.example.android.app/hello
). Bei jeder Suche wird das Slice der Liste hinzugefügt. - Jedes Mal, wenn Sie das Slice Viewer-Tool mit einem Slice-URI starten, wird das Slice der Liste hinzugefügt.
- Sie können ein Slice wischen, um es aus der Liste zu entfernen.
- Tippen Sie auf den URI des Slice, um eine Seite anzuzeigen, die nur diesen Slice enthält. Dies hat denselben Effekt wie das Starten der Slice Viewer mit einem Slice-URI.
Slice-Anzeige mit einer Liste der Slices
Slice in verschiedenen Modi ansehen
Eine Anwendung, in der ein Slice bereitgestellt wird, kann den SliceView#mode
zur Laufzeit ändern. Achten Sie deshalb darauf, dass Ihr Slice in jedem Modus wie erwartet aussieht.
Wählen Sie das Menüsymbol oben rechts auf der Seite aus, um den Modus zu ändern.
Einzel-Slice-Viewer mit Modus „Klein“
Ihren ersten Slice erstellen
Öffnen Sie zum Erstellen eines Slice Ihr Android Studio-Projekt, klicken Sie mit der rechten Maustaste auf das Paket src
und wählen Sie Neu... > Sonstige > Slice-Anbieter. Dadurch wird eine Klasse erstellt, die SliceProvider
erweitert, den erforderlichen Anbietereintrag in die Datei AndroidManifest.xml
aufgenommen und die build.gradle
so ändert, dass die erforderlichen Slice-Abhängigkeiten hinzugefügt werden.
Die Änderung an AndroidManifest.xml
sieht so aus:
<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>
Die folgenden Abhängigkeiten werden zu build.gradle
hinzugefügt:
Kotlin
dependencies { // ... implementation "androidx.slice:slice-builders-ktx:(latest version)" // ... }
Java
dependencies { // ... implementation "androidx.slice:slice-builders:(latest version)" // ... }
Jedem Slice ist ein URI zugeordnet. Wenn mit einer Oberfläche ein Slice angezeigt werden soll, wird mit diesem URI eine Bindungsanfrage an Ihre Anwendung gesendet. Die Anwendung verarbeitet diese Anfrage und erstellt das Slice dynamisch über die Methode onBindSlice
. Auf der Oberfläche kann dann gegebenenfalls das Slice angezeigt werden.
Im Folgenden finden Sie ein Beispiel für eine onBindSlice
-Methode, die den URI-Pfad /hello
prüft und einen Hello World-Slice zurückgibt:
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(); }
Verwenden Sie die Slice-Ausführungskonfiguration, die Sie oben im Abschnitt „Slice-Anzeige“ erstellt haben, und übergeben Sie den Slice-URI (z. B. slice-content://com.android.example.slicesample/hello
) des Hello World-Slice, um ihn in der Slice-Anzeige anzusehen.
Interaktive Slices
Ähnlich wie bei Benachrichtigungen können Sie Klicks im Slice verarbeiten, indem Sie PendingIntent
-Objekte anhängen, die durch eine Nutzerinteraktion ausgelöst werden. Im folgenden Beispiel wird ein Activity
gestartet, der diese Intents empfangen und verarbeiten kann:
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" ); }
Slices unterstützen auch andere Eingabetypen, z. B. Ein-/Aus-Schaltflächen, bei denen der Status im Intent enthalten ist, der an die Anwendung gesendet wird.
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); }
Der Empfänger kann dann den empfangenen Status prüfen:
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(); } } }
Dynamische Slices
Slices können auch dynamische Inhalte enthalten. Im folgenden Beispiel enthält der Slice jetzt die Anzahl der empfangenen Broadcasts im Inhalt:
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); }
In diesem Beispiel wird zwar die Anzahl angezeigt, sie wird aber nicht automatisch aktualisiert. Sie können den Broadcast-Empfänger so anpassen, dass das System mit ContentResolver#notifyChange
über eine Änderung informiert wird.
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); } } }
Vorlagen
Slices unterstützen eine Vielzahl von Vorlagen. Weitere Informationen zu Vorlagenoptionen und -verhalten finden Sie unter Vorlagen.