Advertisement
  1. Code
  2. Android SDK

Codieren Sie Ihr erstes Android-Slice und halten Sie die Benutzer bei der Stange

Scroll to top
Read Time: 22 min

German (Deutsch) translation by Tatsiana Bochkareva (you can also view the original English article)

Die harte Arbeit ist nicht vorbei, nur weil Ihre App eine Menge Downloads und positive Bewertungen im Google Play Store gesammelt hat. Ihr typischer mobiler Benutzer hat Dutzende von Apps auf seinem Gerät installiert, und da ständig neue Apps veröffentlicht werden, müssen Sie hart arbeiten, um das Interesse Ihres Publikums zu wecken!

Um eine stabile, loyale Benutzerbasis zu schaffen, ist es entscheidend, dass Benutzer immer wieder zu Ihrer App zurückkehren. Wenn Sie Ihre App monetarisiert haben, wirkt sich die Zeit, die die Leute in Ihrer Anwendung verbringen, direkt darauf aus, wie viel Geld Sie verdienen. Betrachten Sie jede zusätzliche Sekunde als eine weitere Gelegenheit, eine Anzeige zu schalten oder den Benutzer dazu zu verleiten, sich auf einen In zu stürzen -App-Kauf!

Auf der diesjährigen I/O hat Google Slices vorgestellt, eine neue Funktion, die verspricht, Nutzer zurück zu Ihrer App zu bringen, indem sie die Funktionen und Inhalte Ihrer App genau dann zur Verfügung stellt, wenn sie am dringendsten benötigt werden.

Da sich Slices zu einem wichtigen Werkzeug zur Bindung Ihres Publikums entwickeln, ist jetzt der perfekte Zeitpunkt, um praktische Erfahrungen mit dieser aufstrebenden Android-Funktion zu sammeln. Am Ende dieses Artikels haben Sie eine Reihe von Slices erstellt, von einem einfachen Slice, das beim Antippen eine Aktivität startet, bis hin zu komplexeren Slices, die aus Symbolen, Bildern, Rastern und mehreren SliceActions bestehen.

Slices: Mehr Möglichkeiten für Benutzer, Ihre App zu genießen

Ähnlich wie Widgets sind Slices Inhaltsausschnitte, die außerhalb des Anwendungskontexts erscheinen, die Sichtbarkeit Ihrer App erhöhen und Ihnen mehr Möglichkeiten bieten, Ihr Publikum zu begeistern.

Slices haben das Potenzial, die Sichtbarkeit Ihrer App erheblich zu erhöhen, wobei Google verspricht, die Unterstützung für Slices in den Bereichen hinzuzufügen, in denen viele Android-Benutzer viel Zeit verbringen, einschließlich der Google-Suche und des Google Assistant. Da sie Teil von Android Jetpack sind, sind Slices mit Android 4.4 und höher kompatibel, was bedeutet, dass Ihre Slices das Potenzial haben, 95% aller Android-Benutzer zu erreichen.

Slices haben also viel zu bieten – aber wie funktionieren sie?

Wenn Sie derzeit eine Suche in der Google-App durchführen, schlägt Google möglicherweise eine relevante Anwendung vor, die auf Ihrem Gerät installiert ist. Wenn Sie beispielsweise Facebook für Mobilgeräte installiert haben, wird durch die Eingabe von Facebook ein direkter Link zur Facebook-App angezeigt.

Androids predictive apps suggest the application users might want to interact with next Androids predictive apps suggest the application users might want to interact with next Androids predictive apps suggest the application users might want to interact with next

Slices gehen bei dieser App-Verknüpfung noch einen Schritt weiter, indem sie sich auf bestimmte Aufgaben konzentrieren, die der Benutzer möglicherweise in den bereits installierten Anwendungen ausführen möchte.

Schauen wir uns ein Beispiel an: Stellen Sie sich vor, Sie haben eine Book A Hotel App installiert, mit der Sie nach einem Hotel suchen und ein Zimmer reservieren können. Wenn Sie London Hotels in Google eingeben, sehen Sie die üblichen Suchergebnisse sowie einen Ausschnitt aus der Book A Hotel-Anwendung. Dieses Slice empfiehlt ein Hotel in London und zeigt Informationen wie den Namen und die Adresse des Hotels sowie eine SliceAction in Form einer Schaltfläche an, mit der Sie ein Zimmer direkt über die Benutzeroberfläche (UI) des Slices reservieren können.

Für den Benutzer bietet dieses Slice einen einfachen Zugriff auf die Informationen und Funktionen, die er gerade benötigt. Für Entwickler hat dieser Slice es ihnen ermöglicht, ihre Anwendung genau zu dem Zeitpunkt vor den Benutzer zu bringen, an dem sie die größte Chance hatten, sie erfolgreich erneut zu aktivieren.

Wie erstelle ich mein erstes Slice?

Beginnen wir damit, ein einfaches Slice zu erstellen, das beim Antippen die MainActivity unserer Anwendung startet.

Diese einfache Technik ermöglicht es, jede Aufgabe direkt über die Benutzeroberfläche eines Slices zu starten. In unserem Book A Hotel-Beispiel könnten wir die Schaltfläche einfach mit der BookRoomActivity der zugehörigen App verknüpfen, was eine einfache, aber effektive Möglichkeit wäre, die Anzahl der Bildschirme zu reduzieren, die der Benutzer navigieren muss, um diese spezielle Aufgabe zu erledigen.

Erstellen Sie zunächst ein neues Android-Projekt. Sie können alle gewünschten Einstellungen verwenden, aber stellen Sie sicher, dass Sie das Kontrollkästchen Kotlin-Unterstützung einschließen aktivieren, wenn Sie dazu aufgefordert werden.

Nachdem Sie Ihr Projekt erstellt haben, öffnen Sie die Datei build.gradle und fügen Sie die slice-core- und slice-builder-Abhängigkeiten hinzu:

1
dependencies {
2
   implementation 'androidx.appcompat:appcompat:1.0.0-alpha3'
3
   implementation 'androidx.slice:slice-core:1.0.0-alpha3'
4
   implementation 'androidx.slice:slice-builders:1.0.0-alpha3'
5
   implementation 'androidx.constraintlayout:constraintlayout:1.1.0'
6
   implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
7
}

Anzeigen des Inhalts Ihrer App in der Google-Suche mit Slice-Anbietern

Als Nächstes müssen wir einen Slice-Anbieter erstellen, der die Komponente ist, die für die Anzeige des Inhalts Ihrer App außerhalb des Anwendungskontexts verantwortlich ist.

Sie erstellen einen Slice-Anbieter mithilfe der Slice-Provider-Vorlage von Android Studio:

  • Wählen Sie Neu > Andere > Slice-Anbieter aus der Android Studio-Symbolleiste.
  • Geben Sie den Namen MySliceProvider ein.
  • Stellen Sie die Quellsprache auf Kotlin ein.
  • Klicken Sie auf Fertig stellen.
  • Öffnen Sie die MySliceProvider-Klasse, und Sie sollten den folgenden automatisch generierten Code sehen:
1
import android.content.ContentResolver
2
import android.content.Intent
3
import android.net.Uri
4
import androidx.slice.Slice
5
import androidx.slice.SliceProvider
6
import androidx.slice.builders.ListBuilder
7
8
class MySliceProvider : SliceProvider() {
9
    
10
  override fun onCreateSliceProvider(): Boolean {
11
      return true
12
  }
13
14
  override fun onMapIntentToUri(intent: Intent?): Uri {
15
16
      var uriBuilder: Uri.Builder = Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
17
      if (intent == null) return uriBuilder.build()
18
      val data = intent.data
19
      if (data != null && data.path != null) {
20
          val path = data.path.replace("/", "")
21
          uriBuilder = uriBuilder.path(path)
22
      }
23
      val context = context
24
      if (context != null) {
25
          uriBuilder = uriBuilder.authority(context.getPackageName())
26
      }
27
      return uriBuilder.build()
28
  }
29
30
//Construct the slice//

31
32
  override fun onBindSlice(sliceUri: Uri): Slice? {
33
      val context = getContext() ?: return null
34
      return if (sliceUri.path == "/") {
35
36
//Customise the Slice//

37
38
          ListBuilder(context, sliceUri)
39
                  .addRow { it.setTitle("URI found.") }
40
                  .build()
41
      } else {
42
          
43
          ListBuilder(context, sliceUri)
44
                  .addRow { it.setTitle("URI not found.") }
45
                  .build()
46
      }
47
  }
48
49
//Subscribe to a data source, if necessary//

50
51
  override fun onSlicePinned(sliceUri: Uri?) {
52
53
  }
54
55
//Avoid memory leaks by unsubscribing from the data source and removing any observers//

56
57
  override fun onSliceUnpinned(sliceUri: Uri?) {
58
  }
59
}

Wenn Sie Ihren Slice-Anbieter über Neu > Andere > Slice-Anbieter erstellen, fügt Android Studio auch den erforderlichen Anbieter zu Ihrem Manifest hinzu:

1
 <provider
2
       android:name=".MySliceProvider"
3
       android:authorities="com.jessicathornsby.kotlinslices"
4
       android:exported="true">
5
       <intent-filter>
6
           <action android:name="android.intent.action.VIEW" />
7
           
8
           <category android:name="android.app.slice.category.SLICE" />
9
10
           <data
11
               android:host="jessicathornsby.com"
12
               android:pathPrefix="/"
13
               android:scheme="http" />
14
       </intent-filter>
15
   </provider>
16
</application>

Dieser Eintrag stellt sicher, dass Ihr Slice von anderen Anwendungen erkannt werden kann.

Ist die Synchronisierung Ihres Gradle-Projekts fehlgeschlagen?

Bisher haben wir nur Code verwendet, den Android Studio automatisch generiert hat, aber Ihr Projekt weigert sich möglicherweise bereits, zu kompilieren!

Bugs, fehlende Funktionalität und rundum seltsames Verhalten sind nur ein Teil des Spaßes an der Arbeit mit frühen Releases. Zum Zeitpunkt des Schreibens dieses Artikels fügte das Generieren eines Slice-Providers manchmal unerklärlicherweise eine neue Reihe von Abhängigkeiten zur Datei build.gradle Ihres Projekts hinzu.

1
implementation 'androidx.slice:slices-core:1.0.0-alpha1'
2
implementation 'androidx.slice:slices-builders:1.0.0-alpha1'

Diese Abhängigkeiten sind nicht nur unnötig – sie sind falsch. Obwohl es leicht zu übersehen ist, vergleichen Sie:

1
implementation 'androidx.slice:slices-core:1.0.0-alpha3'

Mit dem richtigen:

1
implementation 'androidx.slice:slice-core:1.0.0-alpha1'

Ein einzelnes s kann den Unterschied zwischen einer funktionierenden Anwendung und einem Projekt ausmachen, das sich weigert zu kompilieren. Es besteht die Möglichkeit, dass dieser Fehler vor der offiziellen Veröffentlichung von Slices behoben wird. Wenn sich Android Studio jedoch über ungelöste Abhängigkeiten beschwert, überprüfen Sie Ihre build.gradle-Datei, um zu sehen, ob dies in Ihrem Projekt passiert ist.

Erstellen eines Slice: URIs, SliceActions und Slice-Layouts

Um den Boilerplate-Code des Slice-Anbieters in einen funktionierenden Slice zu verwandeln, müssen wir mehrere Änderungen vornehmen:

1. Definieren Sie einen URI

Jedes Slice hat einen eindeutigen URI, und es ist die Aufgabe des Slice-Anbieters, die Zuordnung zwischen diesem URI und dem entsprechenden Slice bereitzustellen.

Apps, die ein Slice anzeigen können, werden als Hostanwendungen bezeichnet. Jedes Mal, wenn ein Host ein Slice anzeigen muss, sendet er eine Bindungsanforderung mit dem URI des gesuchten Slice an den Slice-Anbieter. Ihr Slice-Anbieter überprüft dann den URI und gibt den entsprechenden Slice zurück.

Im folgenden Codeausschnitt überprüft die onBindSlice-Methode den /myURI-Pfad und gibt ein Slice zurück, das eine Hello World-Nachricht anzeigt.

1
class MySliceProvider : SliceProvider() {
2
    
3
   override fun onCreateSliceProvider(): Boolean {
4
       return true
5
   }
6
7
   override fun onBindSlice(sliceUri: Uri): Slice? {
8
       return if (sliceUri.path == "/myURI") {
9
           ListBuilder(context, sliceUri, ListBuilder.INFINITY)
10
                   .addRow { it.setTitle("Hello World") }
11
                   .build()
12
       } else {
13
...
14
...
15
...
16
       }
17
   }
18
}

2. Machen Sie Ihr Slice interaktiv

Sie könnten zwar ein Slice erstellen, das lediglich einige Informationen anzeigt, aber wenn Ihr Slice interaktiv sein soll, müssen Sie eine oder mehrere SliceActions erstellen.

Eine SliceAction kann aus einem Titel, einem Symbol und einem PendingIntent bestehen. Sie können SliceActions auch als primäre Aktionen markieren, die ausgelöst werden, wenn der Benutzer irgendwo auf die Zeile dieses Slice tippt.

3. Erstellen Sie die Benutzeroberfläche des Slice

Sie definieren das Layout eines Slices, indem Sie einen ListBuilder implementieren, eine Zeile hinzufügen und dann dieser Zeile Elemente hinzufügen. Hier verwende ich beispielsweise ListBuilder und addRow, um ein Slice zu erstellen, das aus einem Titel und einem Untertitel besteht:

1
import android.net.Uri
2
import androidx.slice.Slice
3
import androidx.slice.SliceProvider
4
import androidx.slice.builders.ListBuilder
5
import androidx.slice.builders.ListBuilder.INFINITY
6
7
class MySliceProvider : SliceProvider() {
8
9
   override fun onCreateSliceProvider(): Boolean {
10
       
11
       return true
12
   }
13
14
   override fun onBindSlice(sliceUri: Uri): Slice? {
15
       val path = sliceUri.path
16
       when (path) {
17
           "/launchMainActivity" -> return createSlice(sliceUri)
18
       }
19
       return null
20
   }
21
22
   fun createSlice(sliceUri: Uri): Slice {
23
       return ListBuilder(context, sliceUri, INFINITY)
24
               .addRow {
25
                   it.apply {
26
                       setTitle("This is a title")
27
                       setSubtitle("This is a subtitle")
28
                       
29
                   }
30
               }.build()
31
   }
32
  
33
}

Sie können eine Mischung verschiedener Inhaltstypen in derselben Zeile anzeigen, z. B. Text, Aktionen und Symbole.

Erstellen Sie Ihr erstes voll funktionsfähiges Android Slice

Lassen Sie uns all dies nun auf unser Projekt anwenden und ein Slice erstellen, das beim Antippen die MainActivity unserer Anwendung startet.

Öffnen Sie die MySliceProvider-Klasse, und fügen Sie Folgendes hinzu:

1
import android.app.PendingIntent
2
import android.content.Intent
3
import android.net.Uri
4
import androidx.core.graphics.drawable.IconCompat
5
import androidx.slice.Slice
6
import androidx.slice.SliceProvider
7
import androidx.slice.builders.ListBuilder
8
import androidx.slice.builders.SliceAction
9
10
//Extend from SliceProvider//

11
12
class MySliceProvider : SliceProvider() {
13
14
//Initialise your slice provider//

15
16
  override fun onCreateSliceProvider(): Boolean {
17
      return true
18
  }
19
20
//Build the slice//

21
22
  override fun onBindSlice(sliceUri: Uri): Slice? {
23
24
//Check the URI path//

25
26
      val path = sliceUri.path
27
      when (path) {
28
29
//Define the slice’s URI; I’m using ‘launchMainActivity’//

30
31
          "/launchMainActivity" -> return createSlice(sliceUri)
32
      }
33
      return null
34
  }
35
36
  fun createSlice(sliceUri: Uri): Slice {
37
      val activityAction = createActivityAction()
38
39
//Create the ListBuilder, which we’ll use to add rows to our slice//

40
41
      val listBuilder = ListBuilder(context!!, sliceUri, ListBuilder.INFINITY)
42
43
//Construct the rows using RowBuilder//

44
45
      val rowBuilder = ListBuilder.RowBuilder(listBuilder)
46
47
//Set the title text//

48
49
              .setTitle("Open MainActivity.")
50
51
//Set the row’s primary action//

52
53
              .setPrimaryAction(activityAction)
54
55
//Add the row to the ListBuilder//

56
57
      listBuilder.addRow(rowBuilder)
58
59
//Build the list//

60
61
      return listBuilder.build()
62
63
  }
64
65
  fun createActivityAction(): SliceAction {
66
      val intent = Intent(context, MainActivity::class.java)
67
      return SliceAction(PendingIntent.getActivity(context, 0, intent, 0),
68
              IconCompat.createWithResource(context!!, R.drawable.ic_home),
69
              "Open MainActivity")
70
  }
71
72
}

Testen Ihrer Slices: Installieren von Slice Viewer

Wenn Sie Ihre Slices auf die Probe stellen möchten, benötigen Sie mindestens eine Anwendung, die Slices anzeigen kann.

Slices werden angeblich noch in diesem Jahr ihr Debüt in der Google-Suche geben, aber zum Zeitpunkt des Schreibens musste diese Funktion noch eingeführt werden. Derzeit besteht die einzige Möglichkeit zum Testen von Slices darin, die Slice Viewer-App von Google zu installieren, die emuliert, wie Slices schließlich in der Google-Suche angezeigt werden.

So installieren Sie Slice Viewer auf einem virtuellen Android-Gerät (AVD):

So installieren Sie Slice Viewer auf einem physischen Smartphone oder Tablet:

  • Laden Sie den Slice-Viewer herunter.
  • Stellen Sie sicher, dass Ihr Smartphone oder Tablet an Ihren Entwicklungscomputer angeschlossen ist.
  • Verschieben Sie das Slice Viewer APK in den Ordner Android/sdk/platform-tools Ihres Computers.
  • Öffnen Sie ein Eingabeaufforderungs- (Windows) oder Terminal- (Mac) Fenster.
  • Ändern Sie das Verzeichnis (cd), sodass die Eingabeaufforderung oder das Terminal auf Ihren Ordner Android/sdk/platform-tools zeigt – zum Beispiel hier mein Befehl:
1
cd /Users/jessicathornsby/Library/Android/sdk/platform-tools
  • Führen Sie den Befehl aus, indem Sie die Eingabetaste auf Ihrer Tastatur drücken.
  • Verwenden Sie den Befehl adb install, um das APK auf Ihr Android-Gerät zu übertragen:
1
./adb install slice-viewer.apk

Erstellen einer URI-Ausführungskonfiguration

Als Nächstes müssen Sie eine Ausführungskonfiguration erstellen, die den einzigartigen URI Ihres Slice an Ihr AVD- oder Android-Gerät übergibt.

  • Wählen Sie Ausführen > Konfigurationen bearbeiten… aus der Android Studio-Symbolleiste.
  • Klicken Sie auf die Schaltfläche + und wählen Sie dann Android-App aus.
Create a run configuration by navigating to Run Edit configurations Android AppCreate a run configuration by navigating to Run Edit configurations Android AppCreate a run configuration by navigating to Run Edit configurations Android App
  • Geben Sie Ihrer Laufkonfiguration einen Namen. Ich verwende sliceConfig.
  • Öffnen Sie das Dropdown-Menü Modul und wählen Sie dann die app aus.
  • Öffnen Sie das Dropdown-Menü Starten und wählen Sie dann URL aus.
  • Geben Sie die URL Ihres Slice im Format slice-content://package-name/slice-URL ein. Die URL meines Slice lautet beispielsweise: slice-content://com.jessicathornsby.kotlinslices/launchMainActivity.
  • OK klicken.
  • Wählen Sie Ausführen > SliceConfig ausführen aus der Android Studio-Symbolleiste und wählen Sie dann Ihr Android-Gerät aus.

Wenn Slice Viewer zum ersten Mal versucht, Ihr Slice anzuzeigen, fordert er die Berechtigung an, auf den eindeutigen URI Ihres Slice zuzugreifen. Tippen Sie auf Zulassen und navigieren Sie durch den Berechtigungsdialog, und Ihr Slice sollte auf dem Bildschirm erscheinen.

The first time you try to display your slice Slice Viewer will request permission to display your applications slicesThe first time you try to display your slice Slice Viewer will request permission to display your applications slicesThe first time you try to display your slice Slice Viewer will request permission to display your applications slices

Um mit der SliceAction zu interagieren, klicken Sie auf die Schaltfläche Open MainActivity, und das Slice reagiert, indem es die MainActivity Ihrer Anwendung startet.

Holen Sie mehr aus Ihren Slices heraus: Hinzufügen einer zweiten SliceAction

Warum sich auf eine SliceAction beschränken, wenn Sie mehrere SliceActions haben können? In diesem Abschnitt implementieren wir zwei SliceActions, bei denen jede Aktion eine andere Activity startet. Ich werde auch ein paar neue UI-Elemente einführen, indem ich unserem Slice einen Untertitel und einige Endelemente hinzufüge.

Erstellen Sie eine zweite Aktivität

Lassen Sie uns das Setup aus dem Weg räumen und eine zweite Activity erstellen, mit der unsere zweite SliceAction verknüpft werden kann.

Wählen Sie zunächst Neu > Kotlin-Datei / Klasse aus der Android Studio-Symbolleiste. Öffnen Sie im Dialogfeld "Neue Datei" das Dropdown-Menü Art und wählen Sie Klasse aus. Benennen Sie diese Klasse SecondActivity, und klicken Sie dann auf OK.

Öffnen Sie nun Ihre SecondActivity-Klasse und fügen Sie Folgendes hinzu:

1
import androidx.appcompat.app.AppCompatActivity
2
import android.os.Bundle
3
4
class SecondActivity : AppCompatActivity() {
5
   override fun onCreate(savedInstanceState: Bundle?) {
6
       super.onCreate(savedInstanceState)
7
       setContentView(R.layout.activity_second)
8
   }
9
}

Wählen Sie als Nächstes Neu > Android-Ressourcendatei aus der Android Studio-Symbolleiste. Öffnen Sie im folgenden Fenster das Dropdown-Menü Ressourcentyp und wählen Sie Layout. Benennen Sie diese Datei activity_second und klicken Sie auf OK.

Öffnen Sie nun diese Layoutdatei und fügen Sie den folgenden Code hinzu:

1
<?xml version="1.0" encoding="utf-8"?>
2
https://schemas.android.com/apk/res/android"
3
   xmlns:app="http://schemas.android.com/apk/res-auto"
4
   xmlns:tools="http://schemas.android.com/tools"
5
   android:layout_width="match_parent"
6
   android:layout_height="match_parent"
7
   tools:context=".MainActivity">
8
9
   <TextView
10
       android:layout_width="wrap_content"
11
       android:layout_height="wrap_content"
12
       android:text="Second Activity"
13
       app:layout_constraintBottom_toBottomOf="parent"
14
       app:layout_constraintLeft_toLeftOf="parent"
15
       app:layout_constraintRight_toRightOf="parent"
16
       app:layout_constraintTop_toTopOf="parent" />
17
18
</androidx.constraintlayout.widget.ConstraintLayout>

Öffnen Sie das Manifest Ihres Projekts und deklarieren Sie diese SecondActivity:

1
<activity android:name=".SecondActivity">

Erstellen komplexerer Benutzeroberflächen: Slice-End-Items

Endelemente können entweder ein Zeitstempel, ein Bild oder eine SliceAction sein, aber wie der Name schon sagt, erscheinen sie immer am Ende einer Zeile. Sie können einer einzelnen Zeile mehrere Endartikel hinzufügen, obwohl es je nach verfügbarem Platz keine Garantie dafür gibt, dass dem Benutzer alle Ihre Endartikel angezeigt werden.

Wir erstellen unsere SliceActions als Symbole, daher müssen Sie Ihrem Projekt zwei neue Drawables hinzufügen:

  • Wählen Sie in der Android Studio-Symbolleiste Neu > Bild-Asset aus.
  • Klicken Sie auf die kleine Schaltfläche ClipArt (dies zeigt standardmäßig ein Bild eines Android an).
  • Wählen Sie das Symbol aus, das Sie für Ihr Endelement Launch MainActivity verwenden möchten. Ich verwende das Home-Symbol.
  • Geben Sie diesem Symbol den Namen ic_home und klicken Sie dann auf Weiter.
  • Lesen Sie die Informationen auf dem Bildschirm und klicken Sie auf Fertig stellen, wenn Sie fortfahren möchten.

Wiederholen Sie die obigen Schritte, um ein Symbol für Ihre Slice-Aktion SecondActivity starten zu erstellen. Für mein zweites Endelement verwende ich das Anrufsymbol und nenne es ic_call.

Erstellen der zweiten Slice-Aktion

Jetzt können wir der MySliceProvider-Klasse eine zweite SliceAction hinzufügen:

1
import android.app.PendingIntent
2
import android.content.Intent
3
import android.net.Uri
4
import androidx.core.graphics.drawable.IconCompat
5
import androidx.slice.Slice
6
import androidx.slice.SliceProvider
7
import androidx.slice.builders.ListBuilder
8
import androidx.slice.builders.SliceAction
9
10
class MySliceProvider : SliceProvider() {
11
    
12
  override fun onCreateSliceProvider(): Boolean {
13
      return true
14
  }
15
16
  override fun onBindSlice(sliceUri: Uri): Slice? {
17
      val path = sliceUri.path
18
      when (path) {
19
          "/launchMainActivity" -> return createSlice(sliceUri)
20
      }
21
      return null
22
  }
23
24
  fun createSlice(sliceUri: Uri): Slice {
25
      val activityAction = createActivityAction()
26
      IconCompat.createWithResource(context!!, R.drawable.ic_home).toIcon()
27
      val activityAction2 = createSecondActivityAction()
28
      IconCompat.createWithResource(context!!, R.drawable.ic_call).toIcon()
29
30
//Construct the parent builder//

31
32
          val listBuilder = ListBuilder(context!!, sliceUri)
33
34
//Construct the builder for the row//

35
36
          val myRow = ListBuilder.RowBuilder(listBuilder)
37
                  .setTitle("Launch MainActivity.")
38
                  .setSubtitle("This is a subtitle")
39
40
//Add the actions that we'll be using as end items//

41
42
          myRow.addEndItem(activityAction)
43
          myRow.addEndItem(activityAction2)
44
45
 //Add the row to the parent builder//

46
47
          listBuilder.addRow(myRow)
48
49
//Build the slice//

50
51
          return listBuilder.build()
52
      }
53
54
  fun createActivityAction(): SliceAction {
55
      val intent = Intent(context, MainActivity::class.java)
56
              return SliceAction(PendingIntent.getActivity(context, 0, intent, 0),
57
                      IconCompat.createWithResource(context!!, R.drawable.ic_home).toIcon(),
58
                      "Launch MainActivity")
59
  }
60
61
  fun createSecondActivityAction(): SliceAction {
62
      val intent = Intent(context, SecondActivity::class.java)
63
      return SliceAction(PendingIntent.getActivity(context, 0, intent, 0),
64
              IconCompat.createWithResource(context!!, R.drawable.ic_call).toIcon(),
65
              "Launch SecondActivity")
66
  }
67
68
}

Da wir den URI nicht geändert haben, müssen wir keine neue Ausführungskonfiguration erstellen, was bedeutet, dass das Testen dieses Slices so einfach ist wie Ausführen > SliceConfig aus der Android Studio-Symbolleiste.

Our slice consists of two end items which are linked to separate SliceActionsOur slice consists of two end items which are linked to separate SliceActionsOur slice consists of two end items which are linked to separate SliceActions

Sie können dieses Projekt aus dem Tutorial GitHub-Repository herunterladen.

Multimedia-Slices: Erstellen von Raster-Layouts

Bisher haben wir alle unsere Slices nur mit Zeilen erstellt, Sie können jedoch auch Slices mit Rasterzeilen und -zellen erstellen.

In diesem letzten Abschnitt erstellen wir ein Slice bestehend aus einem Titel, einem Untertitel und einer einzelnen Zeile, die in drei Zellen unterteilt ist. Jede Zelle hat ihren eigenen Titel, einen Textkörper und ein Bild, und jede Zelle führt beim Antippen eine einzigartige Aktion aus.

Well be creating a grid-based slice consisting of three unique SliceActionsWell be creating a grid-based slice consisting of three unique SliceActionsWell be creating a grid-based slice consisting of three unique SliceActions

Um Ihr Slice in einem Raster anzuordnen, müssen Sie:

  • Implementieren Sie einen ListBuilder.
  • Fügen Sie dem ListBuilder mithilfe von addGridRow eine Rasterzeile hinzu.
  • Fügen Sie mithilfe von addCell Zellen zur Zeile hinzu. Jede Zeile kann maximal fünf Zellen anzeigen.

Sie können dann jeder Zelle Inhalt hinzufügen, z. B.:

  • Ein Titel, den Sie mit addTitleText hinzufügen.
  • Textkörper mit addText.
  • Bilder, die Sie mit addImage erstellen. Jedes Zellenbild muss eines der folgenden Attribute aufweisen: LARGE_IMAGE, SMALL_IMAGE oder ICON_IMAGE.
  • Eine Inhaltsabsicht, die in etwa einer SliceAction entspricht. Um dieses Beispiel übersichtlich zu halten, wird durch Tippen auf jede Zelle einfach ein Artikel im Standardbrowser des Geräts geladen. Wenn Sie jedoch ein authentischeres Slice-Erlebnis bevorzugen, können Sie den setContentIntent-Code ändern.

Ich werde einige Bilder in mein Raster aufnehmen, daher müssen Sie Ihrem Projekt mindestens ein Zeichenobjekt hinzufügen. Ich verwende das Kotlin-Logo, aber Sie können jedes Bild aufnehmen und im Drawable-Ordner Ihres Projekts ablegen.

Jetzt können Sie die MySliceProvider-Klasse öffnen und Ihr Grid erstellen:

1
import android.app.PendingIntent
2
import android.content.Context
3
import android.content.Intent
4
import android.net.Uri
5
import androidx.core.graphics.drawable.IconCompat
6
import androidx.slice.Slice
7
import androidx.slice.SliceProvider
8
import androidx.slice.builders.ListBuilder
9
10
class MySliceProvider : SliceProvider() {
11
12
    override fun onCreateSliceProvider(): Boolean {
13
        return true
14
    }
15
16
    override fun onBindSlice(sliceUri: Uri): Slice? {
17
        val path = sliceUri.path
18
        when (path) {
19
            "/launchMainActivity" -> return createSliceWithGridRow(sliceUri)
20
        }
21
        return null
22
    }
23
24
    fun createSliceWithGridRow(sliceUri: Uri): Slice {
25
        return ListBuilder(context, sliceUri, ListBuilder.INFINITY)
26
                .setHeader {
27
                    it.apply {
28
                        setTitle("Want to start learning Kotlin for Android?")
29
                        setSubtitle("Check out these articles!")
30
                    }
31
                }
32
33
//Add a grid row to the list builder//

34
35
                .addGridRow {
36
                    it.apply {
37
38
//Add a cell to the row//

39
40
                        addCell {
41
                            it.apply {
42
43
//Add content to your cell//

44
45
                                addTitleText("Java vs. Kotlin")
46
                                addText("Part 1")
47
                                addImage(IconCompat.createWithResource(context, R.drawable.kotlin), ListBuilder.LARGE_IMAGE)
48
49
//Specify the intent that should trigger whenever the user interacts with this cell//  

50
51
52
                                        .setContentIntent(
53
                                                loadArticlePendingIntent(
54
                                                        context,
55
                                                        "https://code.tutsplus.com/articles/java-vs-kotlin-should-you-be-using-kotlin-for-android-development...)

56
                            }

57
                        }

58
                        addCell {

59
                            it.apply {

60
                                addTitleText("Coding in Kotlin")

61
                                addText("Part 2")

62
                                addImage(IconCompat.createWithResource(context, R.drawable.kotlin), ListBuilder.LARGE_IMAGE)

63
                                        .setContentIntent(

64
                                                loadArticlePendingIntent(

65
                                                        context,

66
                                                        "https://code.tutsplus.com/tutorials/start-developing-android-apps-with-kotlin-part-1--cms-27827?_ga=...)

67
                            }
68
                        }
69
70
                        addCell {
71
                            it.apply {
72
                                addTitleText("Lambdas & NPE")
73
                                addText("Part 3")
74
                                addImage(IconCompat.createWithResource(context, R.drawable.kotlin), ListBuilder.LARGE_IMAGE)
75
                                        .setContentIntent(
76
                                                loadArticlePendingIntent(
77
                                                        context,
78
                                                        "https://code.tutsplus.com/articles/coding-functional-android-apps-in-kotlin-lambdas-null-safety-more...)

79
                            }
80
                        }
81
                    }
82
                }
83
                .build()
84
    }
85
    private fun loadArticlePendingIntent(context: Context, url: String) =
86
            PendingIntent.getActivity(
87
                    context,
88
                    0,
89
                    Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) },
90
                    0
91
            )
92
}

Den vollständigen Code für dieses Projekt finden Sie in unserem GitHub-Repository.

Führen Sie diese App auf Ihrem AVD oder Ihrem physischen Android-Gerät aus und versuchen Sie, mit jedem Element im Raster zu interagieren. Jede Zelle sollte auf einen anderen Artikel verweisen.

Stellen Sie sicher, dass Ihr Slice unabhängig von der Hostanwendung gut aussieht

Die Art und Weise, wie der Inhalt Ihres Slices angezeigt wird, kann je nach Modus variieren, für den die Hostanwendung konfiguriert ist. Um sicherzustellen, dass Ihre Slices unabhängig von der Hosting-Anwendung gut aussehen und korrekt funktionieren, müssen Sie Ihre Slices in allen verschiedenen Slice-Modi testen.

Da unser Grid-Slice deutlich mehr Inhalt hat als die vorherigen Slices, ist es der beste Kandidat, um die Unterschiede zwischen diesen verschiedenen Slice-Modi zu veranschaulichen.

Um Ihr Slice auf die Probe zu stellen, klicken Sie auf das kleine Symbol in der oberen rechten Ecke des Slice-Viewers und schalten Sie dann durch die folgenden Modi:

1. Groß

In diesem Format zeigt Android so viele Zeilen wie möglich im verfügbaren Platz an. Dies ist der Modus, den Slice Viewer standardmäßig verwendet.

2. Verknüpfung

In diesem Modus wird Ihr Slice durch ein Symbol und eine Beschriftung dargestellt.

In shortcut mode our slice is represented by the Kotlin drawable In shortcut mode our slice is represented by the Kotlin drawable In shortcut mode our slice is represented by the Kotlin drawable

Wenn Ihrer SliceAction ein primärer Header zugeordnet ist, wird dieser als Symbol Ihres Slice verwendet. Wenn kein Symbol verfügbar ist, zeigt Android stattdessen die primäre Aktion an, die mit der ersten Zeile Ihres Slice verbunden ist, die in diesem Fall unsere Kotlin-Zeichnung ist.

Um das im Shortcut-Modus angezeigte Symbol zu ändern, fügen Sie Ihrem Projekt ein zweites Drawable hinzu und aktualisieren Sie dann den folgenden Abschnitt des Slice-Anbieters:

1
               .addGridRow {
2
                   it.apply {
3
                       addCell {
4
                           it.apply {
5
                               addTitleText("Java vs. Kotlin")
6
                               addText("Part 1")
7
8
//Reference the new drawable//

9
10
                               addImage(IconCompat.createWithResource(context, R.drawable.androidlogo), ListBuilder.LARGE_IMAGE)

3. Klein

Der kleine Modus hat eine begrenzte Höhe und zeigt entweder ein einzelnes SliceItem oder eine begrenzte Sammlung von Elementen als einzelne Inhaltszeile an. Wenn Ihr Slice einen Header hat, wird dieser angezeigt, und genau das passiert mit unserem Slice.

In small mode our slice is represented by a title and a subtitle In small mode our slice is represented by a title and a subtitle In small mode our slice is represented by a title and a subtitle

Das Ändern des Titels oder des Untertitels wirkt sich auf den Inhalt aus, der im kleinen Modus angezeigt wird.

1
fun createSliceWithGridRow(sliceUri: Uri): Slice {
2
   return ListBuilder(context, sliceUri, ListBuilder.INFINITY)
3
           .setHeader {
4
               it.apply {
5
               setTitle("This is the title")
6
               setSubtitle("This is the subtitle")
7
               
8
           }
9
       }

Wenn Ihr Slice keine Kopfzeile enthält, wird stattdessen die erste Zeile des Slice angezeigt.

Reduzieren Sie Code mit Slice Builders KTX

Sobald Sie gelernt haben, wie Sie eine neue Funktion implementieren, besteht der nächste Schritt darin, zu lernen, wie Sie mit weniger Code dieselben Ergebnisse liefern!

Android KTX ist eine Sammlung von Modulen, die aus Erweiterungen besteht, die die Android-Plattform für Kotlin optimieren. Das Slice Builders KTX-Modul von Android KTX verpackt das Builder-Muster in eine Kotlin-freundliche DSL, die Ihnen hilft, Ihre Slices prägnanter und lesbarer zu erstellen. Um mit Slice Builders KTX zu beginnen, ersetzen Sie die folgende Abhängigkeit:

1
implementation 'androidx.slice:slice-builders:1.0.0-alpha3'

Mit:

1
implementation 'androidx.slice:slice-builders-ktx:1.0.0-alpha3'

Sie können dann Ihre createSlice-Methode ändern, um diese DSL zu verwenden. Hier ist beispielsweise ein einfaches Slice, das einen Titel und einen Untertitel anzeigt:

1
import android.net.Uri
2
import androidx.slice.Slice
3
import androidx.slice.SliceProvider
4
import androidx.slice.builders.ListBuilder
5
import androidx.slice.builders.ListBuilder.INFINITY
6
7
class MySliceProvider : SliceProvider() {
8
9
   override fun onCreateSliceProvider(): Boolean {
10
       return true
11
   }
12
13
   override fun onBindSlice(sliceUri: Uri): Slice? {
14
       val path = sliceUri.path
15
       when (path) {
16
           "/launchMainActivity" -> return createSlice(sliceUri)
17
       }
18
       return null
19
   }
20
21
   fun createSlice(sliceUri: Uri): Slice {
22
       return ListBuilder(context, sliceUri, INFINITY)
23
               .addRow {
24
                   it.apply {
25
                       setTitle("This is a title")
26
                       setSubtitle("This is a subtitle")
27
28
                   }
29
               }.build()
30
   }
31
32
}

Mit DSL wird daraus:

1
import android.net.Uri
2
import androidx.slice.Slice
3
import androidx.slice.SliceProvider
4
import androidx.slice.builders.ListBuilder
5
import androidx.slice.builders.list
6
import androidx.slice.builders.row
7
8
class MySliceProvider : SliceProvider() {
9
10
   override fun onCreateSliceProvider(): Boolean {
11
       return true
12
   }
13
14
   override fun onBindSlice(sliceUri: Uri): Slice? {
15
       val path = sliceUri.path
16
       when (path) {
17
           "/launchMainActivity" -> return createSlice(sliceUri)
18
       }
19
       return null
20
   }
21
22
   fun createSlice(sliceUri: Uri): Slice {
23
24
//Instantiate a ListBuilder and call build when the lambda has finished running//
25
26
       return list(context, sliceUri, ListBuilder.INFINITY) {
27
28
//Instantiate row and add it to the ListBuilder//
29
30
           row {
31
32
//setTitle and setSubtitle are both inside the row lambda//
33
34
               setTitle("This is a title")
35
               setSubtitle("This is a subtitle")
36
37
           }
38
39
       }
40
   }
41
}

Abschluss

In diesem Artikel haben wir praktische Erfahrungen mit der aufstrebenden Slices-Funktion von Android gesammelt. Wir haben gesehen, wie Sie ein einfaches Slice erstellen, das direkten Zugriff auf jeden Teil Ihrer Anwendung bietet, bevor wir komplexere Slices erstellen, die aus Endelementen, Bildern, zusätzlichem Text und mehreren SliceActions bestehen.

Weitere Informationen zu Slices finden Sie in den offiziellen Android-Dokumenten.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.