Cette page vous explique comment configurer votre environnement et créer des segments d'application dans votre application.
Remarque: Android Studio 3.2 ou version ultérieure contient des outils et des fonctionnalités supplémentaires qui peuvent vous aider à développer des segments d'application:
- Outil de refactorisation AndroidX: obligatoire si vous travaillez sur un projet qui utilise des bibliothèques AndroidX.
- Vérifications lint des segments d'application: détecte les anti-pratiques courants lors de la création de segments d'application
- Modèle
SliceProvider
: gère le code récurrent lors de la création d'unSliceProvider
.
Télécharger et installer la visionneuse de segments d'application
Téléchargez la dernière version d'APK pour la visionneuse de segments d'application que vous pouvez utiliser pour tester vos segments d'application sans implémenter l'API SliceView
.
Si ADB n'est pas configuré correctement dans votre environnement, consultez le guide ADB pour en savoir plus.
Installez la visionneuse de segments d'application sur votre appareil en exécutant la commande suivante dans le même répertoire que le fichier slice-viewer.apk
téléchargé:
adb install -r -t slice-viewer.apk
Exécuter la visionneuse de segments d'application
Vous pouvez lancer le lecteur de segments d'application à partir de votre projet Android Studio ou de la ligne de commande:
Lancez la visionneuse de segments d'application à partir de votre projet Android Studio.
- Dans votre projet, sélectionnez Run > Edit Configurations (Exécuter > Modifier les configurations).
- Dans le coin supérieur gauche, cliquez sur le signe plus vert.
Sélectionnez Application Android.
Saisissez trance (tranche) dans le champ de nom.
Sélectionnez votre module d'application dans le menu déroulant Module.
Sous Launch Options (Options de lancement), sélectionnez URL dans le menu déroulant Launch (Lancer).
Saisissez
slice-<your slice URI>
dans le champ d'URLExemple :
slice-content://com.example.your.sliceuri
Cliquez sur OK.
Lancer la visionneuse de segments d'application via ADB (ligne de commande)
Exécutez votre application depuis Android Studio:
adb install -t -r <yourapp>.apk
Affichez votre segment d'application en exécutant la commande suivante:
adb shell am start -a android.intent.action.VIEW -d slice-<your slice URI>
Lecteur de segment d'application affichant un seul segment d'application Wi-Fi
Afficher tous vos segments d'application au même endroit
En plus de lancer un seul segment d'application, vous pouvez afficher une liste persistante de vos segments d'application.
- Utilisez la barre de recherche pour rechercher manuellement vos segments d'application via un URI (par exemple,
content://com.example.android.app/hello
). Chaque fois que vous effectuez une recherche, le segment d'application est ajouté à la liste. - Chaque fois que vous lancez l'outil de visionneuse de segment d'application avec un URI de segment d'application, celui-ci est ajouté à la liste.
- Vous pouvez balayer un segment d'application pour le supprimer de la liste.
- Appuyez sur l'URI du segment d'application pour afficher une page ne contenant que ce segment d'application. Cela a le même effet que de lancer la visionneuse de segments d'application avec un URI de segment d'application.
Lecteur de segments d'application affichant une liste de segments d'application
Afficher le segment d'application dans différents modes
Une application qui présente un segment d'application peut modifier le SliceView#mode
au moment de l'exécution. Vous devez donc vous assurer qu'il s'affiche comme prévu dans chaque mode.
Pour changer de mode, sélectionnez l'icône de menu en haut à droite de la page.
Visionneuse à tranche unique avec le mode défini sur "petit"
Créer votre premier segment d'application
Pour créer un segment d'application, ouvrez votre projet Android Studio, effectuez un clic droit sur le package src
, puis sélectionnez New... > Autre > Fournisseur de segments d'application. Cette opération crée une classe qui étend SliceProvider
, ajoute l'entrée de fournisseur requise à votre AndroidManifest.xml
et modifie votre build.gradle
pour ajouter les dépendances de segment d'application requises.
La modification apportée à AndroidManifest.xml
est présentée ci-dessous:
<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>
Les dépendances suivantes sont ajoutées à votre build.gradle
:
Kotlin
dependencies { // ... implementation "androidx.slice:slice-builders-ktx:(latest version)" // ... }
Java
dependencies { // ... implementation "androidx.slice:slice-builders:(latest version)" // ... }
Chaque segment d'application est associé à un URI. Lorsqu'une surface souhaite afficher un segment d'application, elle envoie une requête de liaison à votre application avec cet URI. Votre application gère ensuite cette requête et crée le segment d'application de manière dynamique via la méthode onBindSlice
. La surface peut alors afficher le segment d'application, le cas échéant.
Vous trouverez ci-dessous un exemple de méthode onBindSlice
qui recherche le chemin d'URI /hello
et renvoie un segment d'application 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(); }
Utilisez la configuration d'exécution de tranche que vous avez créée dans la section "Lecteur de segment d'application" ci-dessus, en transmettant l'URI de segment d'application (par exemple, slice-content://com.android.example.slicesample/hello
) du segment d'application Hello World pour l'afficher dans la visionneuse de segments d'application.
Segments d'application interactifs
Comme pour les notifications, vous pouvez gérer les clics au sein d'un segment d'application en associant des objets PendingIntent
déclenchés lors d'une interaction de l'utilisateur. L'exemple ci-dessous lance un Activity
pouvant recevoir et gérer ces 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" ); }
Les segments d'application acceptent également d'autres types d'entrées, tels que les boutons d'activation/de désactivation, qui incluent l'état dans l'intent envoyé à l'application.
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); }
Le récepteur peut alors vérifier l'état qu'il reçoit:
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(); } } }
Segments d'application dynamiques
Les segments d'application peuvent également comporter du contenu dynamique. Dans l'exemple suivant, le segment d'application inclut désormais le nombre d'annonces reçues dans son contenu:
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); }
Dans cet exemple, le nombre affiché n'est pas mis à jour automatiquement. Vous pouvez modifier votre broadcast receiver pour avertir le système qu'une modification a eu lieu à l'aide de 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); } } }
Modèles
Les segments d'application sont compatibles avec divers modèles. Pour en savoir plus sur les options et les comportements des modèles, consultez la section Modèles.