# Personnaliser le SDK Android

<Aside type="note">
Assurez-vous d'avoir intégré le SDK Android de Pushwoosh dans votre projet :

*   [Intégration Firebase](/fr/developer/pushwoosh-sdk/android-sdk/firebase-integration/quick-start/)
*   [Intégration Amazon](/fr/developer/pushwoosh-sdk/android-sdk/amazon/)
</Aside>

## Liens profonds

Dans votre activité qui gérera le lien profond, ajoutez la balise \<data> avec les paramètres scheme, host et 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">
Le nom de la page du lien profond (_promotion_ dans l'exemple donné) va dans le champ **host**, et **non pathPrefix**.
</Aside>

Dans l'exemple ci-dessus, le lien profond ouvrira PromoActivity. L'implémentation de base ci-dessous affiche une alerte avec la valeur de l'ID de la promo par souci de simplicité. Dans votre application, cela pourrait certainement faire quelque chose d'utile !

```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();
		}
}
```

## Suivi des achats in-app

Si vous souhaitez suivre les achats in-app dans les [Customer Journeys](/fr/product/customer-journey/pushwoosh-journey-overview), configurez l'envoi des informations d'achat à Pushwoosh en appelant cette méthode :

```java
Pushwoosh.getInstance().sendInappPurchase(@NonNull String sku, @NonNull BigDecimal price, @NonNull String currency);
```

## Notification push par Geozones

Pour utiliser les notifications push par Geozones, ajoutez la bibliothèque `com.pushwoosh:pushwoosh-location` et appelez :

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

Dans votre **AndroidManifest.xml**, incluez les autorisations nécessaires :

```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>
```

## Utilisation des notifications locales avec Pushwoosh

Si vous utilisez l'API de notifications locales de Pushwoosh, ajoutez l'autorisation RECEIVE\_BOOT\_COMPLETED à votre AndroidManifest.xml :

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

## Utilisation du numéro de badge sur Android

Pushwoosh prend en charge la définition du numéro de badge sur le raccourci de l'icône de l'application pour les lanceurs Android suivants :\
Sony, Samsung, LG, HTC, ASUS, ADW, APEX, NOVA, HUAWEI, ZUK, OPPO.\
Pour utiliser cette fonctionnalité, ajoutez simplement la bibliothèque `com.pushwoosh:pushwoosh-badge` à votre application.

## Ouverture d'une activité personnalisée

Si vous souhaitez démarrer une activité particulière en réponse aux notifications push, ajoutez le filtre d'intention suivant à cette activité :

```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>
```

## Contrôle du niveau de journalisation

Afin de faciliter le débogage et l'intégration, le SDK affichera par défaut toutes les requêtes dans la console. Lorsque vous êtes prêt pour la version de production, ajoutez les méta-données `com.pushwoosh.log_level` avec la valeur "ERROR" à l'AndroidManifest.xml. De cette façon, seules les informations sur les erreurs seront affichées dans la console. D'autres options peuvent être l'une des suivantes :

_NONE_ - Aucun journal du SDK\
_ERROR_ - Affiche uniquement les erreurs dans la console\
_WARN_ - Affiche également les avertissements\
_INFO_ - Affiche les messages d'information\
_DEBUG_ - Même les informations de débogage sont maintenant affichées\
_NOISE_ - Tout ce que le SDK peut afficher et plus encore

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

## Utilisation de Proguard

Lors de l'utilisation de Proguard, ajoutez les options suivantes :

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

Consultez les exigences de la bibliothèque **Google Play Services** concernant Proguard ici :\
[https://developers.google.com/android/guides/setup](https://developers.google.com/android/guides/setup)

## Personnalisation du comportement d'ouverture des notifications

Si vous devez sélectionner par programmation l'activité à afficher suite à une notification push, vous pouvez créer une [NotificationServiceExtension](https://github.com/Pushwoosh/pushwoosh-android-sdk/blob/master/Documentation/notification/NotificationServiceExtension.md) personnalisée et inclure le nom de classe complet de votre NotificationServiceExtension dans les métadonnées sous la valeur `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() démarre l'activité de lancement par défaut
      // ou l'activité marquée avec l'action ${applicationId}.MESSAGE.
      // Ne l'appelez tout simplement pas pour remplacer ce comportement.
        // super.startActivityForPushMessage(message);

        // démarrez votre activité à la place :
        Intent launchIntent  = new Intent(getApplicationContext(), YourActivity.class);
        launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        // (Optionnel) passez les données de notification à l'activité
        launchIntent.putExtra(Pushwoosh.PUSH_RECEIVE_EVENT, message.toJson().toString());

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

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

Si vous utilisez proguard dans les builds de production, assurez-vous que votre NotificationServiceExtension personnalisée n'est pas obscurcie (en ajoutant une règle `-keep class`), sinon cela entraînera une ClassNotFoundException.
</Aside>

## Personnalisation des notifications push

Pour personnaliser l'affichage des notifications push, vous devez créer une Factory personnalisée. Vous pouvez créer une [NotificationFactory](https://pushwoosh.github.io/pushwoosh-android-sdk/pushwoosh/com.pushwoosh.notification/-notification-factory/index.html) personnalisée et inclure le nom de classe complet de votre NotificationFactory dans les métadonnées sous la valeur `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 : générer et retourner une notification personnalisée
    }

    // retourner la notification Pushwoosh par défaut
		return super.onGenerateNotification(pushMessage);
	}
}
```

## Personnalisation du résumé de groupe

Pour personnaliser l'apparence d'un [résumé de groupe](https://developer.android.com/training/notify-user/group#set_a_group_summary), créez une Factory personnalisée. Vous pouvez créer une SummaryNotificationFactory personnalisée et inclure le nom de classe complet de votre SummaryNotificationFactory dans les métadonnées sous la valeur 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) {
	      // retournez le message que vous souhaitez
        return super.summaryNotificationMessage(notificationsAmount);
    }
    @Override
    public int summaryNotificationIconResId() {
	      // retournez l'ID de ressource de l'icône que vous souhaitez
        return super.summaryNotificationIconResId();
    }
}
```

## URL de point de terminaison privé

<Aside>
Pour les abonnements au **Plan Personnalisé** uniquement. Pour plus de détails, veuillez contacter notre [équipe commerciale](https://www.pushwoosh.com/demo/?utm_source=docs&utm_medium=post&utm_campaign=customizing-android-sdk).
</Aside>

Pushwoosh fournit des points de terminaison privés pour les clients avec des abonnements au Plan Personnalisé. Pour configurer un point de terminaison privé pour le SDK Android, vous devez ajouter ce qui suit à votre fichier **AndroidManifest.xml** :

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

## Création d'une file d'attente de Rich Media

S'il y a plusieurs pages Rich Media à afficher simultanément (par exemple, des événements déclencheurs pour deux ou plusieurs In-Apps ont lieu en même temps, ou une page Rich Media est déjà affichée au moment où un autre événement déclencheur se produit), vous pouvez configurer une file d'attente pour l'affichage des pages Rich Media. Pour créer une file d'attente, ajoutez le code suivant à votre projet :

```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="Important">
Nous vous recommandons vivement de configurer une file d'attente dans **Application** plutôt que dans **Activity**. Sinon, cela pourrait créer plusieurs files d'attente.
</Aside>

<Aside type="note">
Chaque appel à la méthode [postEvent](/fr/developer/api-reference/user-centric-api/#postevent) ne permet d'afficher qu'un seul In-App, et chaque Push ne peut être associé qu'à un seul Rich Media. Si vous souhaitez afficher plusieurs In-Apps, appelez la méthode [postEvent](/fr/developer/api-reference/user-centric-api/#postevent) le nombre de fois requis.
</Aside>

## Notification push avec son personnalisé

<Aside>
Disponible pour les appareils Android 8+.
</Aside>

1.  Placez votre fichier audio dans le dossier approprié. Pour le framework Android natif, vos fichiers doivent être placés dans le dossier `/app/src/main/res/raw`.

<Aside type="note">
Veuillez vous référer aux guides correspondants pour savoir où placer le fichier audio dans les projets construits avec d'autres frameworks.
</Aside>

2\. Créez un [Canal de Notification.](/fr/developer/pushwoosh-sdk/android-sdk/notification-channels/)

3\. Sélectionnez un son lors de la configuration d'un message push.

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

4\. Définissez le canal de notification auquel le message appartiendra. Pour ce faire, spécifiez ce qui suit dans le champ « Paramètres racine Android » :`{"pw_channel": "NOM DU CANAL DE NOTIFICATION PUSH"} //` `_`ici, vous devez spécifier le nom de votre canal avec un son personnalisé`_`

En cas d'utilisation de l'API distante, définissez les paramètres comme suit dans votre requête API /createMessage :

```java
"android_root_params": {"pw_channel": "push"} // ici, vous devez spécifier le nom de votre canal avec un son personnalisé, par exemple, "push" pour les notifications avec le son push.wav.
"android_sound": "push" // ici, vous devez spécifier le nom du fichier sans extension
```

Une fois que vous avez envoyé la notification push avec ces paramètres spécifiés, le canal de notification avec le son sélectionné est créé pour tous les appareils avec Android 8+.

Maintenant, pour envoyer la notification push avec un son personnalisé, vous devez uniquement spécifier le canal associé à ce son.

### Règles Proguard pour les sons de notification personnalisés

Si votre application utilise proguard pour la réduction du code et des ressources, il est important de conserver vos fichiers sonores intacts et disponibles pour les bibliothèques externes. Si vous utilisez la propriété **`minifyEnabled = true`** dans votre **build.gradle,** ajoutez les règles suivantes à votre **proguard-rules.pro** :

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

Si vous réduisez les ressources de votre application en plus de la réduction du code en utilisant la propriété **`shrinkResources=true`**, vous devez également spécifier les ressources que vous souhaitez conserver. Pour ce faire, créez un nouveau fichier XML avec n'importe quel nom, enregistrez-le quelque part dans votre projet (par exemple, dans res/xml), et spécifiez les noms des ressources sous le paramètre **`tools:keep`** dans la balise **`resources`** :

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

## Liste complète des indicateurs de méta-données du SDK Android

Pour définir un indicateur, vous devez ajouter le bloc de méta-données à votre fichier **AndroidManifest.xml** à l'intérieur de la balise **application**. Par exemple, si vous souhaitez définir l'ID de l'application Pushwoosh, ajoutez le code suivant à votre fichier **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">Indicateur</th><th width="284" align="center">Description</th><th align="center">Valeurs possibles</th></tr></thead><tbody><tr><td align="center">com.pushwoosh.appid</td><td align="center">Définit l'ID de l'application Pushwoosh.</td><td align="center">XXXXX-XXXXX</td></tr><tr><td align="center">com.pushwoosh.log_level</td><td align="center">Définit le niveau de journalisation. Pour plus de détails, consultez <a href="#controlling-log-level">Contrôle du niveau de journalisation</a>. </td><td align="center">NONE / ERROR / WARN / INFO / <strong>DEBUG</strong> (<em>par défaut</em>) / NOISE</td></tr><tr><td align="center">com.pushwoosh.base_url</td><td align="center">Remplace l'URL de base du serveur Pushwoosh.</td><td align="center"><a href="https://cp.pushwoosh.com/json/1.3/">https://cp.pushwoosh.com/json/1.3/</a> (<em>par défaut</em>)</td></tr><tr><td align="center">com.pushwoosh.notification_service_extension</td><td align="center">NotificationServiceExtension personnalisé. Pour plus de détails, consultez <a href="#customising-notification-open-behaviour">Personnalisation du comportement d'ouverture des notifications</a>.  </td><td align="center">com.myapp.MyNotificationServiceExtension</td></tr><tr><td align="center">com.pushwoosh.notification_factory</td><td align="center"><p>NotificationFactory personnalisé.</p><p>Pour plus de détails, consultez <a href="#customizing-push-notifications">Personnalisation des notifications 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 personnalisé.</td><td align="center">com.myapp.MySummaryNotificationFactory</td></tr><tr><td align="center">com.pushwoosh.multi_notification_mode</td><td align="center">Si vrai, les notifications seront groupées. Si faux, seule la dernière notification reçue sera affichée.</td><td align="center">vrai / <strong>faux</strong> (<em>par défaut</em>)</td></tr><tr><td align="center">com.pushwoosh.allow_server_communication</td><td align="center">Si vrai, le SDK est autorisé à envoyer des requêtes réseau aux serveurs Pushwoosh.</td><td align="center"><strong>vrai</strong> (<em>par défaut</em>) / faux</td></tr><tr><td align="center">com.pushwoosh.handle_notifications_using_workmanager</td><td align="center">Si vrai, le WorkManager est configuré pour gérer les notifications.</td><td align="center">vrai / <strong>faux</strong> (<em>par défaut</em>)</td></tr><tr><td align="center">com.pushwoosh.notification_icon</td><td align="center">Nom de la ressource de l'icône de notification personnalisée (petite). Si nul, l'icône de l'application par défaut sera utilisée. </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">Couleur de fond de l'icône de notification (petite).</td><td align="center">#FFFFFF</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_data</td><td align="center">Si vrai, le SDK est autorisé à collecter et à envoyer les données de l'appareil à Pushwoosh.</td><td align="center"><strong>vrai</strong> (<em>par défaut</em>) / faux</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_os_version</td><td align="center">Si vrai, le SDK est autorisé à collecter et à envoyer la version de l'OS de l'appareil à Pushwoosh.</td><td align="center"><strong>vrai</strong> (<em>par défaut</em>) / faux</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_locale</td><td align="center">Si vrai, le SDK est autorisé à collecter et à envoyer les paramètres régionaux de l'appareil à Pushwoosh.</td><td align="center"><strong>vrai</strong> (<em>par défaut</em>) / faux</td></tr><tr><td align="center">com.pushwoosh.allow_collecting_device_model</td><td align="center">Si vrai, le SDK est autorisé à collecter et à envoyer le modèle de l'appareil à Pushwoosh.</td><td align="center"><strong>vrai</strong> (<em>par défaut</em>) / faux</td></tr><tr><td align="center">com.pushwoosh.in_app_business_solutions_capping</td><td align="center">Limite le nombre de fois que l'In-App <em>push-unregister</em> peut être affiché par jour.</td><td align="center"><strong>1</strong> (<em>par défaut</em>), 2, ..., n</td></tr><tr><td align="center">com.pushwoosh.start_foreground_service</td><td align="center">Si vrai, le service de premier plan est lancé avec l'appel PushwooshLocation.startLocationTracking()</td><td align="center">vrai / <strong>faux</strong> (<em>par défaut</em>)</td></tr><tr><td align="center">com.pushwoosh.foreground_service_notification_text</td><td align="center">Définit le texte d'une notification créée lorsque le service de premier plan est lancé pour la clé « com.pushwoosh.start_foreground_service ».</td><td align="center"><strong>Travail en cours</strong> (<em>par défaut</em>)</td></tr><tr><td align="center">com.pushwoosh.foreground_service_notification_channel_name</td><td align="center">Définit le nom du canal pour la notification créée lorsque le service de premier plan est lancé pour la clé « com.pushwoosh.start_foreground_service ». </td><td align="center"><strong>Service de premier plan</strong> (<em>par défaut)</em></td></tr><tr><td align="center">com.pushwoosh.trusted_package_names</td><td align="center">Permet de partager le HWID de Pushwoosh avec le package spécifié</td><td align="center">"com.mycompany.myapp1, com.mycompany.myapp2"</td></tr></tbody></table>

## Suppression des notifications push via TTL (Time-To-Live)

Pour supprimer automatiquement les notifications push après une période spécifiée en utilisant le TTL (Time-to-Live), suivez ces étapes :

1.  Créez une NotificationFactory personnalisée. [En savoir plus](#customizing-push-notifications)

2.  Dans la méthode `onGenerateNotification()`, créez une notification en utilisant la classe `Notification.Builder` ou `NotificationCompat.Builder` et appelez la méthode `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)
                                           // reste de votre code de création de notification
                                           .setTimeoutAfter(timeout) // temps en millisecondes avant l'annulation de la notification
                                           .build();
    }
}

```

## Partagez vos commentaires avec nous

Vos commentaires nous aident à créer une meilleure expérience, nous serions donc ravis de vous entendre si vous rencontrez des problèmes lors du processus d'intégration du SDK. Si vous rencontrez des difficultés, n'hésitez pas à nous faire part de vos réflexions via [ce formulaire](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform).