Erste Schritte

Auf dieser Seite erfahren Sie, wie Sie Ihre Umgebung einrichten Segmente in Ihrer App.

Hinweis: Android Studio 3.2 oder höher enthält zusätzliche Tools und Funktionen, die Sie bei der Slice-Entwicklung unterstützen:

  • Refactoring-Tool von AndroidX: erforderlich, wenn Sie an einem Projekt arbeiten, AndroidX-Bibliotheken verwendet.
  • Slices Lint-Prüfungen: Erkennt gängige Anti-Practices beim Bauen Segmente
  • Vorlage SliceProvider: verarbeitet den Textbaustein, wenn SliceProvider wird erstellt

Slice Viewer herunterladen und installieren

Neuestes Beispiel herunterladen APK-Release des Slice-Viewers mit denen Sie Ihre Slices testen können, ohne SliceView API

Falls ADB in Ihrer Umgebung nicht richtig eingerichtet ist, finden Sie weitere Informationen in der ADB-Leitfaden (in englischer Sprache)

Installieren Sie den Slice Viewer auf Ihrem Gerät, indem Sie den folgenden Befehl im demselben Verzeichnis wie der heruntergeladene slice-viewer.apk:

adb install -r -t slice-viewer.apk

Slice-Viewer ausführen

Sie können den Slice Viewer entweder von Ihrem Android Studio-Projekt aus der Befehlszeile:

Slice Viewer aus Ihrem Android Studio-Projekt starten

  1. Wählen Sie in Ihrem Projekt Ausführen > Konfigurationen bearbeiten...
  2. Klicken Sie links oben auf das grüne Pluszeichen.
  3. Wähle Android-App aus.

  4. Geben Sie slice in das Namensfeld ein.

  5. Wählen Sie im Drop-down-Menü Modul Ihr App-Modul aus

  6. Wählen Sie unter Startoptionen im Drop-down-Menü Einführung die Option URL aus.

  7. Geben Sie slice-<your slice URI> in das URL-Feld ein.

    Beispiel: slice-content://com.example.your.sliceuri

  8. 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 Ihr Slice mit dem folgenden Befehl auf:

adb shell am start -a android.intent.action.VIEW -d slice-<your slice URI>

Slice-Anzeige mit einem einzelnen WLAN-Slice

Alle Slices an einem Ort ansehen

Neben dem Starten eines einzelnen Slice können Sie eine dauerhafte Liste Ihrer Segmente.

  • Verwenden Sie die Suchleiste, um manuell über den URI nach Ihren Slices zu suchen (z. B. content://com.example.android.app/hello. Bei jeder Suche wird das Slice wurden der Liste hinzugefügt.
  • Jedes Mal, wenn Sie das Tool „Slice Viewer“ mit einem Slice-URI starten, wird das Slice hinzugefügt. zur Liste hinzugefügt.
  • Du kannst ein Slice wischen, um es aus der Liste zu entfernen.
  • Tippen Sie auf den URI des Slice, um eine Seite aufzurufen, die nur dieses Slice enthält. Dies hat Es hat denselben Effekt wie beim Starten des Slice-Viewers mit einem Slice-URI.

Slice-Viewer mit einer Liste der Slices

Slice in verschiedenen Modi ansehen

Eine App, die ein Slice präsentiert, kann das SliceView#mode während der Laufzeit. Daher sollten Sie darauf achten, dass Ihr Slice in jedem Modus wie erwartet aussieht. Wählen Sie oben rechts auf der Seite das Menüsymbol aus, um den Modus zu ändern.

Einzel-Slice-Viewer mit Modus „klein“

Erstes Slice erstellen

Um ein Slice zu erstellen, öffnen Sie Ihr Android Studio-Projekt, klicken Sie mit der rechten Maustaste auf Ihr src Paket und wählen Sie Neu... &gt; Sonstiges > Slice-Anbieter. Dadurch wird eine Klasse erstellt, die sich über SliceProvider erstreckt, den erforderlichen Anbietereintrag in AndroidManifest.xml und ändert Ihre build.gradle, um die erforderlichen Slice-Abhängigkeiten hinzuzufügen.

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 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 auf einer Oberfläche ein Slice angezeigt werden soll, sendet mit diesem URI eine Bindungsanfrage an Ihre Anwendung. Die App übernimmt dann und erstellt das Slice dynamisch über die onBindSlice . Bei Bedarf kann das Slice dann auf der Oberfläche angezeigt werden.

Unten sehen Sie ein Beispiel für eine onBindSlice-Methode, mit der nach dem /hello-URI gesucht wird. und gibt ein Hello World-Slice zurück:

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 Konfiguration für die Slice-Ausführung, die Sie im Abschnitt „Slice-Anzeige“ erstellt haben. und den Slice-URI übergeben, z. B. slice-content://com.android.example.slicesample/hello) von Hello World Slice, um ihn in der Slice-Anzeige anzusehen.

Interaktive Segmente

Ähnlich wie bei Benachrichtigungen können Sie Klicks innerhalb Ihres Slice verarbeiten, indem Sie PendingIntent-Objekte, die die durch eine Nutzerinteraktion ausgelöst werden. Im folgenden Beispiel wird ein Activity, die diese empfangen und verarbeiten können. Intents:

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, die den Status in den an die App gesendeten Intent.

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 Segmente

Segmente können auch dynamische Inhalte enthalten. Im folgenden Beispiel wird das Segment enthält die Anzahl der im Inhalt empfangenen Übertragungen:

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 die Anzahl zwar angezeigt, aber nicht automatisch aktualisiert. Sie können den Übertragungsempfänger ändern, um das System über eine Änderung zu informieren mit 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);
        }
    }
}

Vorlagen

Slices unterstützen eine Vielzahl von Vorlagen. Weitere Informationen zu den Vorlagenoptionen und finden Sie unter Vorlagen.