# Personalizar el SDK de Android

<Aside type="note">
Asegúrese de haber integrado el SDK de Android de Pushwoosh en su proyecto:

* [Integración con Firebase](/es/developer/pushwoosh-sdk/android-sdk/firebase-integration/quick-start/)
* [Integración con Amazon](/es/developer/pushwoosh-sdk/android-sdk/amazon/)
</Aside>

## Enlaces profundos

En su actividad que manejará el enlace profundo, agregue la etiqueta \<data> con los parámetros scheme, host y pathPrefix.

```txt
<activity
          android:name=".PromoActivity"
          android:label="PromoActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="com.pushwoosh"
          android:host="promotion"
          android:pathPrefix="" />
    </intent-filter>
</activity>
```

<Aside type="note">
El nombre de la página del enlace profundo (_promotion_ en el ejemplo dado) va en el campo **host**, **no en pathPrefix**.
</Aside>

En el ejemplo anterior, el enlace profundo abrirá PromoActivity. La implementación básica a continuación muestra una alerta con el valor del id de la promoción por simplicidad. ¡En su aplicación definitivamente podría hacer algo útil!

```java
public class PromoActivity extends Activity
{
		@Override
		protected void onCreate(Bundle savedInstanceState)
		{
				super.onCreate(savedInstanceState);

				setContentView(R.layout.deep_link);
				setTitle("Deep link activity");

				Intent intent = getIntent();
	  	  String action = intent.getAction();
	    	Uri data = intent.getData();

		    if (TextUtils.equals(action, Intent.ACTION_VIEW))
		    {
	  		  	openUrl(data);
		    }
		}

		private void openUrl(Uri uri)
		{
				String promoId = uri.getQueryParameter("id");
				Toast.makeText(getApplicationContext(), promoId, Toast.LENGTH_LONG).show();
		}
}
```

## Seguimiento de compras in-app

Si desea realizar un seguimiento de las compras in-app en [Customer Journeys](/es/product/customer-journey/pushwoosh-journey-overview), configure el envío de información de compra a Pushwoosh llamando a este método:


```java
Pushwoosh.getInstance().sendInappPurchase(@NonNull String sku, @NonNull BigDecimal price, @NonNull String currency);
```
## Notificación push de Geozones  

Para usar pushes de Geozone, agregue la biblioteca `com.pushwoosh:pushwoosh-location` y llame a:  

```java
PushwooshLocation.startLocationTracking();
```

En su **AndroidManifest.xml**, incluya los permisos necesarios:


```xml
<manifest ... >
  <!-- Required for geolocation-based push notifications -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Required for precise location tracking -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

  <!-- Required for background location access on Android 10 (API level 29) and higher -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>
```

## Usar notificaciones locales con Pushwoosh

Si utiliza la API de Notificaciones Locales de Pushwoosh, agregue el permiso RECEIVE\_BOOT\_COMPLETED a su AndroidManifest.xml:

```txt title="AndroidManifest.xml"
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>x
```


## Usar número de insignia en Android

Pushwoosh admite la configuración del número de insignia en el acceso directo del ícono de la aplicación para los siguientes lanzadores de Android:\
Sony, Samsung, LG, HTC, ASUS, ADW, APEX, NOVA, HUAWEI, ZUK, OPPO.\
Para usar esta funcionalidad, simplemente agregue la biblioteca `com.pushwoosh:pushwoosh-badge` a su aplicación.

## Abrir actividad personalizada

Si desea iniciar una actividad particular en respuesta a las notificaciones push, agregue el siguiente intent-filter a esa actividad:

```txt title="AndroidManifest.xml"
<activity android:name="YourActivity">
    <intent-filter>
        <action android:name="${applicationId}.MESSAGE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
```

## Controlar el nivel de registro (Log Level)

Para ayudar con la depuración y la integración, el SDK imprimirá todas las solicitudes en la consola de forma predeterminada. Cuando esté listo para la compilación de producción, agregue los metadatos `com.pushwoosh.log_level` con el valor "ERROR" al AndroidManifest.xml. De esta manera, solo la información sobre errores irá a la consola. Otra opción podría ser una de las siguientes:

_NONE_ - Sin registros del SDK\
_ERROR_ - Mostrar solo errores en la consola\
_WARN_ - Mostrar también advertencias\
_INFO_ - Mostrar mensajes informativos\
_DEBUG_ - Ahora se muestra incluso la información de depuración\
_NOISE_ - Todo lo que el SDK puede imprimir y más

```txt title="AndroidManifest.xml"
<meta-data android:name="com.pushwoosh.log_level" android:value="ERROR" />
```

## Usar Proguard

Cuando use Proguard, agregue las siguientes opciones:

```txt title="proguard-rules.pro"
-keep class com.pushwoosh.** { *; }
-dontwarn com.pushwoosh.**
```

Vea los requisitos de la biblioteca de **Google Play Services** con respecto a Proguard aquí:\
[https://developers.google.com/android/guides/setup](https://developers.google.com/android/guides/setup)

## Personalizar el comportamiento de apertura de notificaciones

Si necesita seleccionar programáticamente qué actividad mostrar como resultado de una notificación push, puede crear una [NotificationServiceExtension](https://github.com/Pushwoosh/pushwoosh-android-sdk/blob/master/Documentation/notification/NotificationServiceExtension.md) personalizada e incluir el nombre de clase completamente calificado de su NotificationServiceExtension en los metadatos bajo el valor `com.pushwoosh.notification_service_extension`.

```txt title="AndroidManifest.xml"
<meta-data
    android:name="com.pushwoosh.notification_service_extension"
    android:value="com.your.package.YourNotificationServiceExtension" />
```

```java title="YourNotificationServiceExtension.java"
public class YourNotificationServiceExtension extends NotificationServiceExtension {
    @Override
    protected void startActivityForPushMessage(PushMessage message) {
      // super.startActivityForPushMessage() inicia la actividad de lanzamiento predeterminada
      // o la actividad marcada con la acción ${applicationId}.MESSAGE.
      // Simplemente no lo llame para anular este comportamiento.
        // super.startActivityForPushMessage(message);

        // inicie su actividad en su lugar:
        Intent launchIntent  = new Intent(getApplicationContext(), YourActivity.class);
        launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        // (Opcional) pasar datos de notificación a la Actividad
        launchIntent.putExtra(Pushwoosh.PUSH_RECEIVE_EVENT, message.toJson().toString());

        context.startActivity(launchIntent);
    }
}
```

<Aside type="note">
**Importante**

Si usa proguard en compilaciones de producción, asegúrese de que su NotificationServiceExtension personalizado no esté ofuscado (agregando la regla `-keep class`), de lo contrario, provocará una ClassNotFoundException.
</Aside>

## Personalizar notificaciones push

Para personalizar la vista de las notificaciones push, necesita crear una Factory personalizada, puede crear una [NotificationFactory](https://pushwoosh.github.io/pushwoosh-android-sdk/pushwoosh/com.pushwoosh.notification/-notification-factory/index.html) personalizada e incluir el nombre de clase completamente calificado de su NotificationFactory en los metadatos bajo el valor `com.pushwoosh.notification_factory`.

```txt title="AndroidManifest.xml"
<meta-data
    android:name="com.pushwoosh.notification_factory"
    android:value="com.your.package.YourNotificationFactory" />
```

```java title="YourNotificationFactory"
public class YourNotificationFactory extends PushwooshNotificationFactory {
	@Override
	public Notification onGenerateNotification(@NonNull PushMessage pushMessage) {
		if (customNotification) {
       // TODO: generar y devolver una notificación personalizada
    }

    // devolver la notificación predeterminada de Pushwoosh
		return super.onGenerateNotification(pushMessage);
	}
}
```

## Personalizar el resumen del grupo

Para personalizar la apariencia de un [resumen de grupo](https://developer.android.com/training/notify-user/group#set_a_group_summary), cree una Factory personalizada. Puede crear una SummaryNotificationFactory personalizada e incluir el nombre de clase completamente calificado de su SummaryNotificationFactory en los metadatos bajo el valor com.pushwoosh.summary\_notification\_factory.

```java title="AndroidManifest.xml"
<meta-data
    android:name="com.pushwoosh.summary_notification_factory"
    android:value="com.your.package.YourSummaryNotificationFactory" />
```

```java title="YourSummaryNotificationFactory"
public class YourSummaryNotificationFactory extends PushwooshSummaryNotificationFactory {
    @Override
    public String summaryNotificationMessage(int notificationsAmount) {
	      // devuelva el mensaje que desee
        return super.summaryNotificationMessage(notificationsAmount);
    }
    @Override
    public int summaryNotificationIconResId() {
	      // devuelva el id del recurso del ícono que desee
        return super.summaryNotificationIconResId();
    }
}
```

## URL de punto final privado

<Aside>
Solo para suscripciones del **Plan Personalizado**. Para más detalles, por favor contacte a nuestro [equipo de Ventas](https://www.pushwoosh.com/demo/?utm_source=docs&utm_medium=post&utm_campaign=customizing-android-sdk).
</Aside>

Pushwoosh proporciona puntos finales privados para clientes con suscripciones al Plan Personalizado. Para configurar un punto final privado para el SDK de Android, debe agregar lo siguiente a su archivo **AndroidManifest.xml**:

```txt title="AndroidManifest.xml"
<meta-data android:name="com.pushwoosh.base_url" android:value="PUSHWOOSH_PRIVATE_ENDPOINT_URL_PROVIDED" />
```

## Crear una cola de Rich Media

En caso de que haya varias páginas de Rich Media para mostrar simultáneamente (por ejemplo, los eventos de activación para dos o más In-Apps tienen lugar en un momento, o una página de Rich Media ya se está mostrando en el momento en que ocurre un evento de activación diferente), puede configurar una cola para la visualización de páginas de Rich Media. Para crear una cola, agregue el siguiente código a su proyecto: 

```java title="Application.java"
package com.pushwoosh.testingapp;

import com.pushwoosh.RichMediaManager;
import com.pushwoosh.exception.PushwooshException;
import com.pushwoosh.richmedia.RichMediaPresentingDelegate;
import com.pushwoosh.richmedia.RichMedia;
import com.pushwoosh.internal.utils.PWLog;

import java.util.ArrayDeque;
import java.util.concurrent.locks.ReentrantLock;

public class DefaultRichMediaPresentingDelegate implements RichMediaPresentingDelegate {
    private final String TAG = DefaultRichMediaPresentingDelegate.class.getSimpleName();
    private ArrayDeque<RichMedia> richMediaQueue = new ArrayDeque<>();
    private RichMedia currentRichMedia = null;
    private ReentrantLock reentrantLock;

    public DefaultRichMediaPresentingDelegate() {
        PWLog.noise(TAG, "new DefaultRichMediaPresentingDelegate:" + this);
        reentrantLock = new ReentrantLock();
    }

    @Override
    public boolean shouldPresent(RichMedia richMedia) {
        PWLog.noise(TAG, "shouldPresent:" + richMedia);
        if (currentRichMedia == null) {
            PWLog.noise(TAG, "currentRichMedia is null");
        }
        if (richMedia.isLockScreen()) {
            PWLog.noise(TAG, "isLockScreen is true");
            return true;
        }
        try {
            reentrantLock.lock();
            if (currentRichMedia == null) {
                PWLog.noise(TAG, "show:" + richMedia);
                currentRichMedia = richMedia;
                return true;
            } else {
                PWLog.noise(TAG, "add to queue:" + richMedia);
                richMediaQueue.add(richMedia);
                return false;
            }
        } finally {
            reentrantLock.unlock();
        }
    }

    @Override
    public void onPresent(RichMedia richMedia) {
        PWLog.noise(TAG, "onPresent" + richMedia);
    }

    @Override
    public void onError(RichMedia richMedia, PushwooshException pushwooshException) {
        PWLog.error(TAG, pushwooshException + " richMedia:"+richMedia.toString());
        tryShowNextRichMediaThreadSafety();
    }

    @Override
    public void onClose(RichMedia richMedia) {
        PWLog.noise(TAG, "onClose:" + richMedia);
        tryShowNextRichMediaThreadSafety();
    }

    private void tryShowNextRichMediaThreadSafety() {
        try {
            reentrantLock.lock();
            tryShowNextRichMedia();
        } finally {
            reentrantLock.unlock();
        }
    }

    private void tryShowNextRichMedia() {
        if (!richMediaQueue.isEmpty()) {
			currentRichMedia = richMediaQueue.poll();
			PWLog.noise(TAG, "try manual show:" + currentRichMedia);
			RichMediaManager.present(currentRichMedia);
		} else {
			PWLog.noise(TAG, "richMediaQueue is empty");
			currentRichMedia = null;
		}
    }
}
```

<Aside type="caution" title="Importante">
Recomendamos encarecidamente configurar una cola en **Application** en lugar de en **Activity**. De lo contrario, podría crear varias colas.
</Aside>

<Aside type="note">
Cada llamada al método [postEvent](/es/developer/api-reference/user-centric-api/#postevent) solo permite que se muestre una In-App, y cada Push solo puede asociarse con una Rich Media. Si desea mostrar múltiples In-Apps, llame al método [postEvent](/es/developer/api-reference/user-centric-api/#postevent) el número de veces requerido.
</Aside>

## Push con sonido personalizado

<Aside>
Disponible para dispositivos con Android 8+. 
</Aside>

1. Coloque su archivo de audio en la carpeta adecuada. Para el framework nativo de Android, sus archivos deben colocarse en la carpeta `/app/src/main/res/raw`. 

<Aside type="note">
Por favor, consulte las guías correspondientes para encontrar dónde colocar el archivo de audio en proyectos construidos en otros frameworks. 
</Aside>

2\. Cree un [Canal de Notificación.](/es/developer/pushwoosh-sdk/android-sdk/notification-channels/)

3\. Seleccione un sonido mientras configura un mensaje push.

<img src="/android-push-notifications-customizing-android-sdk-5.0-1.webp" alt=""/>

4\. Establezca el Canal de Notificación al que pertenecerá el mensaje. Para hacerlo, especifique lo siguiente en el campo “Android root params”:`{"pw_channel": "PUSH NOTIFICATION CHANNEL NAME"} //`` `_`aquí necesita especificar el nombre para su canal con sonido personalizado`_

En caso de usar la API remota, establezca los parámetros de la siguiente manera dentro de su solicitud de API /createMessage:

```java
"android_root_params": {"pw_channel": "push"} // aquí necesita especificar el nombre para su canal con sonido personalizado, por ejemplo, "push" para las notificaciones con sonido push.wav.
"android_sound": "push" // aquí debe especificar el nombre del archivo sin extensión
```

Una vez que envíe el push con esos parámetros especificados, se crea el Canal de Notificación con el sonido seleccionado para todos los dispositivos con Android 8+. 

Ahora, para enviar el push con un sonido personalizado, solo tiene que especificar el canal asociado con ese sonido.

### Reglas de Proguard para sonidos de notificación personalizados

Si su aplicación utiliza proguard para la reducción de código y recursos, es importante mantener sus archivos de sonido intactos y disponibles para bibliotecas externas. Si utiliza la propiedad **`minifyEnabled = true`** en su **build.gradle,** agregue las siguientes reglas a su **proguard-rules.pro**:

```
-keep public class your.package.name.R$raw {
 *;
}
```

Si reduce los recursos de su aplicación además de la reducción de código usando la propiedad **`shrinkResources=true`**, debe especificar adicionalmente qué recursos desea conservar. Para ello, cree un nuevo archivo XML con cualquier nombre, guárdelo en algún lugar de su proyecto (por ejemplo, en res/xml) y especifique los nombres de los recursos bajo el parámetro **`tools:keep`** en la etiqueta **`resources`**:

```
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
 tools:keep="@raw/*"
/>
```

## Lista completa de indicadores de metadatos del SDK de Android

Para configurar un indicador, debe agregar el bloque de metadatos a su archivo **AndroidManifest.xml** dentro de la etiqueta **application**. Por ejemplo, si desea establecer el ID de la aplicación Pushwoosh, agregue el siguiente código a su archivo **AndroidManifest.xml**:

```txt title="AndroidManifest.xml"
<meta-data
    android:name="com.pushwoosh.appid"
    android:value="XXXXX-XXXXX" />
```

<table><thead><tr><th width="262.33243208828077" align="center">Indicador</th><th width="284" align="center">Descripción</th><th align="center">Valores posibles</th></tr></thead><tbody><tr><td align="center">com.pushwoosh.appid</td><td align="center">Establece el ID de la aplicación Pushwoosh.</td><td align="center">XXXXX-XXXXX</td></tr><tr><td align="center">com.pushwoosh.log_level</td><td align="center">Establece el nivel de registro. Para más detalles, consulte <a href="#controlling-log-level">Controlar el nivel de registro</a>. </td><td align="center">NONE / ERROR / WARN / INFO / <strong>DEBUG</strong> (<em>predeterminado</em>) / NOISE</td></tr><tr><td align="center">com.pushwoosh.base_url</td><td align="center">Sobrescribe la URL base del servidor de Pushwoosh.</td><td align="center"><a href="https://cp.pushwoosh.com/json/1.3/">https://cp.pushwoosh.com/json/1.3/</a> (<em>predeterminado</em>)</td></tr><tr><td align="center">com.pushwoosh.notification_service_extension</td><td align="center">NotificationServiceExtension personalizado. Para más detalles, consulte <a href="#customising-notification-open-behaviour">Personalizar el comportamiento de apertura de notificaciones</a>.  </td><td align="center">com.myapp.MyNotificationServiceExtension</td></tr><tr><td align="center">com.pushwoosh.notification_factory</td><td align="center"><p>NotificationFactory personalizado.</p><p>Para más detalles, consulte <a href="#customizing-push-notifications">Personalizar notificaciones push</a>. </p></td><td align="center">com.myapp.MyNotificationFactory</td></tr><tr><td align="center">com.pushwoosh.summary_notification_factory</td><td align="center">SummaryNotificationFactory personalizado.</td><td align="center">com.myapp.MySummaryNotificationFactory</td></tr><tr><td align="center">com.pushwoosh.multi_notification_mode</td><td align="center">Si es verdadero, la notificación se agrupará. Si es falso, solo se mostrará la última notificación recibida.</td><td align="center">true / <strong>false</strong> (<em>predeterminado</em>)</td></tr><tr><td align="center">com.pushwoosh.allow_server_communication</td><td align="center">Si es verdadero, el SDK tiene permitido enviar solicitudes de red a los servidores de Pushwoosh.</td><td align="center"><strong>true</strong> (<em>predeterminado</em>) / false</td></tr><tr><td align="center">com.pushwoosh.handle_notifications_using_workmanager</td><td align="center">Si es verdadero, el WorkManager se establece para manejar las notificaciones.</td><td align="center">true / <strong>false</strong> (<em>predeterminado</em>)</td></tr><tr><td align="center">com.pushwoosh.notification_icon</td><td align="center">Nombre del recurso del ícono de notificación personalizado (pequeño). Si es nulo, se usará el ícono de la aplicación predeterminado. </td><td align="center">res/drawable-xxhdpi-v11/notification_small_icon.png / null</td></tr><tr><td align="center">com.pushwoosh.notification_icon_color</td><td align="center">Color de fondo del ícono de notificación (pequeño).</td><td align="center">#FFFFFF</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_data</td><td align="center">Si es verdadero, el SDK tiene permitido recopilar y enviar datos del dispositivo a Pushwoosh.</td><td align="center"><strong>true</strong> (<em>predeterminado</em>) / false</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_os_version</td><td align="center">Si es verdadero, el SDK tiene permitido recopilar y enviar la versión del sistema operativo del dispositivo a Pushwoosh.</td><td align="center"><strong>true</strong> (<em>predeterminado</em>) / false</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_locale</td><td align="center">Si es verdadero, el SDK tiene permitido recopilar y enviar la configuración regional del dispositivo a Pushwoosh.</td><td align="center"><strong>true</strong> (<em>predeterminado</em>) / false</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_model</td><td align="center">Si es verdadero, el SDK tiene permitido recopilar y enviar el modelo del dispositivo a Pushwoosh.</td><td align="center"><strong>true</strong> (<em>predeterminado</em>) / false</td></tr><tr><td align="center">com.pushwoosh.in_app_business_solutions_capping</td><td align="center">Limita el número de veces que la In-App <em>push-unregister</em> puede mostrarse en un día.</td><td align="center"><strong>1</strong> (<em>predeterminado</em>), 2, ..., n</td></tr><tr><td align="center">com.pushwoosh.start_foreground_service</td><td align="center">Si es verdadero, el Servicio en Primer Plano se inicia junto con la llamada a PushwooshLocation.startLocationTracking()</td><td align="center">true / <strong>false</strong> (<em>predeterminado</em>)</td></tr><tr><td align="center">com.pushwoosh.foreground_service_notification_text</td><td align="center">Establece el texto de una notificación creada cuando se inicia el Servicio en Primer Plano para la clave “com.pushwoosh.start_foreground_service”.</td><td align="center"><strong>Work in progress</strong> (<em>predeterminado</em>)</td></tr><tr><td align="center">com.pushwoosh.foreground_service_notification_channel_name</td><td align="center">Establece el nombre del canal para la notificación creada cuando se inicia el Servicio en Primer Plano para la clave “com.pushwoosh.start_foreground_service”. </td><td align="center"><strong>Foreground service</strong> (<em>predeterminado)</em></td></tr><tr><td align="center">com.pushwoosh.trusted_package_names</td><td align="center">Permite compartir el HWID de Pushwoosh con el paquete especificado</td><td align="center">"com.mycompany.myapp1, com.mycompany.myapp2"</td></tr></tbody></table>


## Eliminar notificaciones push mediante TTL (Time-To-Live)

Para eliminar automáticamente las notificaciones push después de un período de tiempo especificado usando TTL (Time-to-Live), siga estos pasos:

1. Cree una NotificationFactory personalizada. [Aprenda más](#customizing-push-notifications)

2. En el método `onGenerateNotification()`, cree una notificación usando la clase `Notification.Builder` o `NotificationCompat.Builder` y llame al método `setTimeoutAfter`:

```java
public class YourNotificationFactory extends PushwooshNotificationFactory {

    @Override
    public Notification onGenerateNotification(@NonNull PushMessage pushMessage) {
        Notification.Builder builder = new Notification.Builder(getApplicationContext(), addChannel(pushData));

        Notification notification = builder.setContentText(pushData.getMessage())
                                           .setContentTitle(title)
                                           .setContentText(text)
                                           // resto de su código de creación de notificaciones
                                           .setTimeoutAfter(timeout) // tiempo en milisegundos antes de que se cancele la notificación
                                           .build();
    }
}

```

## Comparta sus comentarios con nosotros

Sus comentarios nos ayudan a crear una mejor experiencia, por lo que nos encantaría saber de usted si tiene algún problema durante el proceso de integración del SDK. Si enfrenta alguna dificultad, no dude en compartir sus pensamientos con nosotros a través de [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform).