
Con la indexación de contenido personal, la app genera resultados de la búsqueda en Google app que incluyen contenido vinculado con la cuenta del usuario. Los usuarios solo ven contenido personal en sus dispositivos en los resultados personales y en las sugerencias de Búsqueda.
Por ejemplo, si un usuario busca “receta de pollo favorita”, la pestaña de resultados personales incluye la nota que agregó a una receta de pollo en una app culinaria.
Si la app no incluye contenido personal, puedes omitir este paso y dirigirte directamente a Registra acciones de los usuarios.
Antes de comenzar, asegúrate de admitir vínculos al contenido de la app y de agregar la biblioteca de App Indexing a ella.
Establece el índice y agrega objetos
Crea una clase que extienda JobIntentService
.
La implementación descrita en este documento se basa en la clase JobIntentService
para poner en fila las actualizaciones al índice del dispositivo, pero puedes usar una clase alternativa a fin de programar el trabajo.
Si realizas la implementación a través de la clase JobIntentService
, asegúrate de agregar también la biblioteca de compatibilidad de Android al archivo build.gradle
del proyecto.
Para incluir elementos en el índice de contenido personal de la app, crea objetos Indexable
en la misma clase:
- Si quieres crear objetos indexables de una manera más conveniente, usa las clases de compiladores existentes cuando sea posible (por ejemplo, MessageBuilder, DigitalDocumentBuilder y PersonBuilder). Consulta una lista de clases de compiladores comunes.
- Para los tipos de contenido que no cuentan con compiladores personalizados, usa la clase genérica
Indexable.Builder()
. - Agrega más información mediante tipos y propiedades de datos predefinidos de Schema.org.
Tipos de resultados
App Indexing te permite mostrar tus resultados de las siguientes dos maneras:
- Solo texto: La Búsqueda de Google muestra tu contenido indexado como resultados de texto.
- Segmentos: La Búsqueda de Google usa segmentos o plantillas de IU de tu app para proporcionar resultados de la búsqueda interactivos y dinámicos.
Puedes elegir el tipo de resultado que mejor se adapte a tu app. Los resultados de solo texto son menos complicados de implementar. Sin embargo, los segmentos ofrecen una mejor experiencia del usuario.
Ejemplo de implementación
Java
Android
public class AppIndexingUpdateService extends JobIntentService { // Job-ID must be unique across your whole app. private static final int UNIQUE_JOB_ID = 42; public static void enqueueWork(Context context) { enqueueWork(context, AppIndexingUpdateService.class, UNIQUE_JOB_ID, new Intent()); } @Override protected void onHandleWork(@NonNull Intent intent) { // TODO Insert your Indexable objects — for example, the recipe notes look as follows: ArrayList<Indexable> indexableNotes = new ArrayList<>(); for (Recipe recipe : getAllRecipes()) { Note note = recipe.getNote(); if (note != null) { Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder() .setName(recipe.getTitle() + " Note") .setText(note.getText()) .setUrl(recipe.getNoteUrl()) .build(); indexableNotes.add(noteToIndex); } } if (indexableNotes.size() > 0) { Indexable[] notesArr = new Indexable[indexableNotes.size()]; notesArr = indexableNotes.toArray(notesArr); // batch insert indexable notes into index FirebaseAppIndex.getInstance().update(notesArr); } } // ... }
Kotlin
Android
class AppIndexingUpdateService : JobIntentService() { companion object { // Job-ID must be unique across your whole app. private const val UNIQUE_JOB_ID = 42 fun enqueueWork(context: Context) { JobIntentService.enqueueWork(context, AppIndexingUpdateService::class.java, UNIQUE_JOB_ID, Intent()) } } override fun onHandleWork(intent: Intent) { // TODO Insert your Indexable objects — for example, the recipe notes look as follows: val indexableNotes = arrayListOf<Indexable>() for (recipe in getAllRecipes()) { val note = recipe.note if (note != null) { val noteToIndex = Indexables.noteDigitalDocumentBuilder() .setName(recipe.title + " Note") .setText(note.text) .setUrl(recipe.noteUrl) .build() indexableNotes.add(noteToIndex) } } if (indexableNotes.size > 0) { val notesArr: Array<Indexable> = indexableNotes.toTypedArray() // batch insert indexable notes into index FirebaseAppIndex.getInstance().update(*notesArr) } } // ... }
Los segmentos te permiten designar porciones de tu app para que aparezcan como resultados de la Búsqueda de Google. Actúan como una IU para el contenido de objetos Indexables
, por lo que cada segmento debería asignarse a un objeto Indexable
. Sigue estos pasos para generar resultados en segmentos de tu app:
- Sigue las instrucciones de la Guía de introducción a los segmentos para agregar segmentos a tu app.
- Agrega objetos
Indexables
con los agentes de escucha y los metadatos de los segmentos:
package com.example.myapp; import android.content.Context; import android.content.Intent; import android.support.annotation.NonNull; import android.support.v4.app.JobIntentService; import com.google.firebase.appindexing.builders.Indexables; import com.google.firebase.appindexing.FirebaseAppIndex; import com.google.firebase.appindexing.Indexable; import java.util.ArrayList; public class AppIndexingUpdateService extends JobIntentService { // Job-ID must be unique across your whole app. private static final int UNIQUE_JOB_ID = 42; public static void enqueueWork(Context context) { enqueueWork(context, AppIndexingUpdateService.class, UNIQUE_JOB_ID, new Intent()); } @Override protected void onHandleWork(@NonNull Intent intent) { // TODO Insert your Indexable objects — for example, the recipe notes look as follows: ArrayList<Indexable> indexableNotes = new ArrayList<>(); for (Recipe recipe : getAllRecipes()) { Note note = recipe.getNote(); if (note != null) { Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder() .setName(recipe.getTitle() + " Note") .setText(note.getText()) .setUrl(recipe.getNoteUrl()) .setMetadata( new Indexable.Metadata.Builder().setSliceUri( Uri.parse("content://com.example.myapp.sliceprovider/note?id=" + recipe.getNoteId()) )) .build(); indexableNotes.add(noteToIndex); } } if (indexableNotes.size() > 0) { Indexable[] notesArr = new Indexable[indexableNotes.size()]; notesArr = indexableNotes.toArray(notesArr); // batch insert indexable notes into index FirebaseAppIndex.getInstance().update(notesArr) .addOnSuccessListener(unused -> { Log.d("RecipeApp", "Update succeeded!"); }) .addOnFailureListener(exception -> { Log.d("RecipeApp", "Update failed: " + exception); }); } } }
¿Qué debe incluir el índice de contenido personal?
Define los objetos Indexable
para los siguientes tipos de contenido:
- El contenido específico de los usuarios, como mensajes, fotos o documentos.
- El contenido que es importante para los usuarios, como sus favoritos o el contenido al que, tal vez, quieran acceder con más frecuencia. Por ejemplo, los documentos o las canciones que marcaron o seleccionaron para usar sin conexión.
- El contenido que se genera dentro de la app, no solo el que se consulta mediante ella. Por ejemplo, los contactos que crean los usuarios directamente dentro de la app y que se almacenan en esta, en lugar de los contactos del directorio del teléfono.
Agrega un receptor de transmisión a la app
Los Servicios de Google Play envían periódicamente una solicitud a la app para actualizar el índice del dispositivo. Esta acción permite que el índice tenga el contenido más reciente de tu app en el dispositivo.
La clase BroadcastReceiver
recibe esta solicitud y activa JobIntentService para procesar el trabajo de indexación. El siguiente ejemplo usa la clase AppIndexingUpdateService
del paso anterior.
Java
Android
/** Receives broadcast for App Indexing Update. */ public class AppIndexingUpdateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent != null && FirebaseAppIndex.ACTION_UPDATE_INDEX.equals(intent.getAction())) { // Schedule the job to be run in the background. AppIndexingUpdateService.enqueueWork(context); } } }
Kotlin
Android
/** Receives broadcast for App Indexing Update. */ class AppIndexingUpdateReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent?) { if (intent != null && FirebaseAppIndex.ACTION_UPDATE_INDEX == intent.action) { // Schedule the job to be run in the background. AppIndexingUpdateService.enqueueWork(context) } } }
Genera y actualiza el índice
A continuación, permite que los Servicios de Google Play llamen al servicio de Indexación de aplicaciones para actualizar el índice en el dispositivo con el contenido personal del usuario en estas tres situaciones:
- Cuando la app se instala en un dispositivo.
- Si se actualiza una versión existente de la app a una versión compatible con la indexación de contenido personal.
- Llamadas periódicas para reflejar correctamente los cambios que se produzcan en el contenido indexado a fin de garantizar una experiencia del usuario sin problemas.
Además, si se pierde el índice en el dispositivo por algún motivo (p. ej., si se daña), esta llamada para actualizar el índice restablecerá el contenido.
En el archivo AndroidManifest.xml
, registra el BroadcastReceiver
para que pueda recibir llamadas desde los Servicios de Google Play y actualizar el índice. En el siguiente ejemplo, se usa la clase JobIntentService para programar las actualizaciones de indexación:
<!-- Register the BroadcastReceiver --> <receiver android:name=".AppIndexingUpdateReceiver" android:exported="true" android:permission="com.google.android.gms.permission.APPINDEXING"> <intent-filter> <action android:name="com.google.firebase.appindexing.UPDATE_INDEX" /> </intent-filter> </receiver> <!-- Grant the AppIndexingUpdateService permission and enable it to run after being triggered --> <service android:name=".AppIndexingUpdateService" android:permission="android.permission.BIND_JOB_SERVICE" />
Actualiza el índice
Cuando los usuarios agregan, actualizan o quitan contenido personal, el índice en el dispositivo debe reflejar esos cambios. Agrega el siguiente código para actualizar el contenido del índice:
Java
Android
public void indexNote(Recipe recipe) { Note note = recipe.getNote(); Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder() .setName(recipe.getTitle()) .setText(note.getText()) .setUrl(recipe.getNoteUrl()) .build(); Task<Void> task = FirebaseAppIndex.getInstance().update(noteToIndex); // ... }
Kotlin
Android
fun indexNote(recipe: Recipe) { val note = recipe.note val noteToIndex = Indexables.noteDigitalDocumentBuilder() .setName(recipe.title) .setText(note!!.text) .setUrl(recipe.noteUrl) .build() val task = FirebaseAppIndex.getInstance().update(noteToIndex) // ... }
Firebase App Indexing recupera el contenido del segmento cuando se efectúa la indexación, lo almacena y muestra el resumen del segmento cuando se realiza la consulta. Si el contenido del segmento cambia entre el paso de indexación y el de consulta, el resumen podría ser engañoso o confuso para los usuarios. Si quieres evitar lo anterior, actualiza el segmento y vuelve a indexar el objeto indexable al mismo tiempo a fin de que Firebase App Indexing siempre tenga el contenido más reciente.
private void indexNote() { Note note = mRecipe.getNote(); Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder() .setName(mRecipe.getTitle()) .setText(note.getText()) .setUrl(mRecipe.getNoteUrl()) .setKeywords("recipe", "cooking") .setMetadata( new Indexable.Metadata.Builder().setSliceUri( Uri.parse("content://com.example.myapp.sliceprovider/note?id=" + note.getNoteId()))) .build(); Task<Void> task = FirebaseAppIndex.getInstance().update(noteToIndex); ... }
Para identificar los elementos que deben quitarse, usa la URL del elemento. Agrega la siguiente línea a la función de borrar o quitar de la app correspondiente a ese elemento.
Java
Android
// Deletes or removes the corresponding notes from index. String noteUrl = recipe.getNoteUrl(); FirebaseAppIndex.getInstance().remove(noteUrl);
Kotlin
Android
// Deletes or removes the corresponding notes from index. val noteUrl = recipe.noteUrl FirebaseAppIndex.getInstance().remove(noteUrl)
Borra el índice cuando los usuarios salgan
Borra el índice en el dispositivo cuando los usuarios salgan de la app, durante el evento de salida.
Incluye la llamada para generar y actualizar el índice en el dispositivo a través de AppIndexingService
a fin de que este se vuelva a completar cuando los usuarios accedan nuevamente.
Para borrar el índice en el dispositivo, cuando un usuario sale de la app, agrega el siguiente fragmento de código:
Java
Android
FirebaseAppIndex.getInstance().removeAll();
Kotlin
Android
FirebaseAppIndex.getInstance().removeAll()