Incidents App Center (Android)

Important

La mise hors service de Visual Studio App Center est prévue pour le 31 mars 2025. Bien que vous puissiez continuer à utiliser Visual Studio App Center jusqu’à sa mise hors service complète, il existe plusieurs alternatives recommandées vers lesquelles vous pouvez envisager la migration.

En savoir plus sur les chronologies et les alternatives de support.

Les incidents App Center génèrent automatiquement un journal des incidents chaque fois que votre application plante. Le journal est d’abord écrit dans le stockage de l’appareil et lorsque l’utilisateur redémarre l’application, le rapport d’incident est envoyé à App Center. La collecte des incidents fonctionne à la fois pour les applications bêta et en direct, c’est-à-dire celles soumises à Google Play. Les journaux d’incident contiennent des informations précieuses pour vous aider à résoudre l’incident.

Suivez la section Prise en main si vous n’avez pas encore configuré le Kit de développement logiciel (SDK) dans votre application.

Générer un incident de test

App Center Crashs vous fournit une API pour générer un plantage de test afin de tester facilement le Kit de développement logiciel (SDK). Cette API ne peut être utilisée que dans les builds de débogage et ne fait rien dans les builds de mise en production.

Crashes.generateTestCrash();
Crashes.generateTestCrash()

Obtenir plus d’informations sur un incident précédent

App Center Crashes a deux API qui vous donnent plus d’informations en cas de blocage de votre application.

L’application a-t-elle reçu un avertissement de mémoire insuffisante lors de la session précédente ?

À tout moment après le démarrage du Kit de développement logiciel (SDK), vous pouvez case activée si l’application a reçu un avertissement de mémoire lors de la session précédente :

Crashes.hasReceivedMemoryWarningInLastSession();
Crashes.hasReceivedMemoryWarningInLastSession()

Cette API est asynchrone. Vous pouvez en savoir plus à ce sujet dans notre guide des API asynchrones App Center .

Notes

Cette méthode ne doit être utilisée qu’après Crashes le démarrage. Elle est toujours retournée false avant le démarrage.

Notes

Dans certains cas, un appareil avec une mémoire insuffisante ne peut pas envoyer d’événements.

L’application s’est-elle planté lors de la session précédente ?

À tout moment après le démarrage du SDK, vous pouvez case activée si l’application s’est bloquée au lancement précédent :

Crashes.hasCrashedInLastSession();
Crashes.hasCrashedInLastSession()

Cette API est asynchrone. Vous pouvez en savoir plus à ce sujet dans notre guide des API asynchrones App Center .

Cela s’avère pratique si vous souhaitez ajuster le comportement ou l’interface utilisateur de votre application après un incident. Certains développeurs ont choisi d’afficher une interface utilisateur supplémentaire pour s’excuser auprès de leurs utilisateurs, ou veulent entrer en contact après un incident.

Notes

Cette méthode ne doit être utilisée qu’après Crashes le démarrage. Elle est toujours retournée false avant le démarrage.

Détails sur le dernier incident

Si votre application s’est bloquée précédemment, vous pouvez obtenir des détails sur le dernier incident.

Crashes.getLastSessionCrashReport();
Crashes.getLastSessionCrashReport()

Cette API est asynchrone. Vous pouvez en savoir plus à ce sujet dans notre guide des API asynchrones App Center .

Il existe de nombreux cas d’usage pour cette API, le plus courant étant les personnes qui appellent cette API et implémentent leur CrashListener personnalisé.

Notes

Cette méthode ne doit être utilisée qu’après Crashes le démarrage. Elle est toujours retournée null avant le démarrage.

Personnaliser votre utilisation des incidents App Center

Les incidents App Center fournissent des rappels permettant aux développeurs d’effectuer des actions supplémentaires avant et lors de l’envoi des journaux d’incident à App Center.

Pour gérer les rappels, implémentez toutes les méthodes dans l’interface CrashesListener ou remplacez la AbstractCrashesListener classe et choisissez uniquement celles qui vous intéressent.

Utiliser votre propre CrashListener

Créez votre propre CrashListener et affectez-le comme suit :

CrashesListener customListener = new CrashesListener() {
    // Implement all callbacks here.
};
Crashes.setListener(customListener);
val customListener = object : CrashesListener {
    // Implement all callbacks here.
}
Crashes.setListener(customListener)

Si vous souhaitez uniquement personnaliser certains rappels, utilisez à la AbstractCrashesListener place :

AbstractCrashesListener customListener = new AbstractCrashesListener() {
    // Implement any callback here as required.
};
Crashes.setListener(customListener);
val customListener = object : AbstractCrashesListener() {
    // Implement any callback here as required.
}
Crashes.setListener(customListener)

Notes

Définissez l’écouteur avant d’appeler AppCenter.start(), car App Center démarre le traitement se bloque immédiatement après le démarrage.

L’incident doit-il être traité ?

Implémentez ce rappel si vous souhaitez décider si un incident particulier doit être traité ou non. Par exemple, il peut y avoir un incident au niveau du système que vous souhaitez ignorer et que vous ne souhaitez pas envoyer à App Center.

@Override
public boolean shouldProcess(ErrorReport report) {
    return true; // return true if the crash report should be processed, otherwise false.
}
override fun shouldProcess(report: ErrorReport?): Boolean {
    return true
}

Si la confidentialité des utilisateurs est importante pour vous, vous souhaiterez peut-être obtenir une confirmation de l’utilisateur avant d’envoyer un rapport d’incident à App Center. Le Kit de développement logiciel (SDK) expose un rappel qui indique aux incidents App Center d’attendre la confirmation de l’utilisateur avant d’envoyer des rapports d’incident.

Si vous avez choisi de le faire, il vous incombe d’obtenir la confirmation de l’utilisateur, par exemple via une invite de dialogue avec l’une des options suivantes : Toujours envoyer, Envoyer et Ne pas envoyer. En fonction de l’entrée, vous indiquerez aux incidents App Center ce qu’il faut faire et le plantage sera ensuite géré en conséquence.

Notes

Le SDK n’affiche pas de boîte de dialogue pour cela. L’application doit fournir sa propre interface utilisateur pour demander le consentement de l’utilisateur.

Le rappel suivant montre comment indiquer au SDK d’attendre la confirmation de l’utilisateur avant d’envoyer des incidents :

@Override
public boolean shouldAwaitUserConfirmation() {

    // Build your own UI to ask for user consent here. SDK doesn't provide one by default.

    // Return true if you built a UI for user consent and are waiting for user input on that custom UI, otherwise false.
    return true;
}
override fun shouldAwaitUserConfirmation(): Boolean {
    return true
}

Si vous retournez true, votre application doit obtenir (à l’aide de votre propre code) l’autorisation de l’utilisateur et envoyer un message au SDK avec le résultat à l’aide de l’API suivante :

// Depending on the user's choice, call Crashes.notifyUserConfirmation() with the right value.
Crashes.notifyUserConfirmation(Crashes.DONT_SEND);
Crashes.notifyUserConfirmation(Crashes.SEND);
Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND);
Crashes.notifyUserConfirmation(Crashes.DONT_SEND)
Crashes.notifyUserConfirmation(Crashes.SEND)
Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND)

À titre d’exemple, vous pouvez vous référer à notre exemple de dialogue personnalisé.

Obtenir des informations sur les status d’envoi d’un journal d’incident

Parfois, vous souhaitez connaître la status de l’incident de votre application. Un cas d’usage courant est que vous souhaiterez peut-être afficher l’interface utilisateur qui indique aux utilisateurs que votre application envoie un rapport d’incident, ou, si votre application se bloque rapidement après le lancement, vous souhaitez ajuster le comportement de l’application pour vous assurer que les journaux d’incident peuvent être envoyés. Les incidents App Center ont trois rappels différents que vous pouvez utiliser dans votre application pour être averti de ce qui se passe :

Le rappel suivant sera appelé avant que le SDK envoie un journal d’incident

@Override
public void onBeforeSending(ErrorReport errorReport) {
    // Your code, e.g. to present a custom UI.
}
override fun onBeforeSending(report: ErrorReport?) {
    // Your code, e.g. to present a custom UI.
}

Si nous avons des problèmes réseau ou une panne sur le point de terminaison et que vous redémarrez l’application, onBeforeSending est à nouveau déclenchée après le redémarrage du processus.

Le rappel suivant sera appelé une fois que le SDK a correctement envoyé un journal d’incident

@Override
public void onSendingSucceeded(ErrorReport report) {
    // Your code, e.g. to hide the custom UI.
}
override fun onSendingSucceeded(report: ErrorReport?) {
    // Your code, e.g. to hide the custom UI.
}

Le rappel suivant sera appelé si le SDK n’a pas pu envoyer un journal d’incident

@Override
public void onSendingFailed(ErrorReport report, Exception e) {
    // Your code goes here.
}
override fun onSendingFailed(report: ErrorReport?, e: Exception?) {
    // Your code goes here.
}

onSendingFailed La réception signifie qu’une erreur non récupérable telle qu’un code 4xx s’est produite. Par exemple, 401 signifie que le appSecret est incorrect.

Ce rappel n’est pas déclenché s’il s’agit d’un problème réseau. Dans ce cas, le Kit de développement logiciel (SDK) continue de réessayer (et interrompt également les nouvelles tentatives lorsque la connexion réseau est interrompue).

Ajouter des pièces jointes à un rapport d’incident

Vous pouvez ajouter des pièces jointes binaires et de texte à un rapport d’incident. Le Kit de développement logiciel (SDK) les envoie avec le plantage afin que vous puissiez les voir dans le portail App Center. Le rappel suivant sera appelé juste avant d’envoyer le blocage stocké à partir des lancements précédents de l’application. Il ne sera pas appelé lorsque l’incident se produit. Assurez-vous que le fichier de pièce jointe n’est pas nommé minidump.dmp , car ce nom est réservé aux fichiers minidump. Voici un exemple montrant comment joindre du texte et une image à un incident :

@Override
public Iterable<ErrorAttachmentLog> getErrorAttachments(ErrorReport report) {

    // Attach some text.
    ErrorAttachmentLog textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt");

    // Attach binary data.
    byte[] binaryData = getYourBinary();
    ErrorAttachmentLog binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg");

    // Return attachments as list.
    return Arrays.asList(textLog, binaryLog);
}
override fun getErrorAttachments(report: ErrorReport?): MutableIterable<ErrorAttachmentLog> {

    // Attach some text.
    val textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt")

    // Attach binary data.
    val binaryData = getYourBinary()
    val binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg")

    // Return attachments as list.
    return listOf(textLog, binaryLog)
}

Notes

La limite de taille est actuellement de 7 Mo. La tentative d’envoi d’une pièce jointe plus volumineuse déclenche une erreur.

Activer ou désactiver les incidents App Center au moment de l’exécution

Vous pouvez activer et désactiver les incidents App Center au moment de l’exécution. Si vous le désactivez, le SDK n’effectuera aucun rapport d’incident pour l’application.

Crashes.setEnabled(false);
Crashes.setEnabled(false)

Pour réactiver les incidents true App Center, utilisez la même API, mais passez en tant que paramètre.

Crashes.setEnabled(true);
Crashes.setEnabled(true)

L’état est conservé dans le stockage de l’appareil au cours des lancements d’application.

Cette API est asynchrone. Vous pouvez en savoir plus à ce sujet dans notre guide des API asynchrones App Center .

Notes

Cette méthode ne doit être utilisée qu’après Crashes le démarrage.

Vérifier si les incidents App Center sont activés

Vous pouvez également case activée si les incidents App Center sont activés ou non :

Crashes.isEnabled();
Crashes.isEnabled()

Cette API est asynchrone. Vous pouvez en savoir plus à ce sujet dans notre guide des API asynchrones App Center .

Notes

Cette méthode ne doit être utilisée qu’après Crashes le démarrage. Elle est toujours retournée false avant le démarrage.

Erreurs gérées

App Center vous permet également de suivre les erreurs à l’aide d’exceptions gérées. Pour ce faire, utilisez la trackError méthode :

try {
    // your code goes here.
} catch (Exception exception) {
    Crashes.trackError(exception);
}
try {
    // your code goes here.
} catch (exception: Exception) {
    Crashes.trackError(exception)
}

Une application peut éventuellement attacher des propriétés à un rapport d’erreurs géré pour fournir un contexte supplémentaire. Transmettez les propriétés en tant que mappage de paires clé/valeur (chaînes uniquement) comme indiqué dans l’exemple ci-dessous.

try {
    // your code goes here.
} catch (Exception exception) {
    Map<String, String> properties = new HashMap<String, String>() {{
        put("Category", "Music");
        put("Wifi", "On");
    }};
    Crashes.trackError(exception, properties, null);
}
try {
    // your code goes here.
} catch (exception: Exception) {
    val properties = mapOf("Category" to "Music", "Wifi" to "On")
    Crashes.trackError(exception, properties, null)
}

Vous pouvez également ajouter des pièces jointes binaires et de texte à un rapport d’erreurs géré. Passez les pièces jointes en tant que comme Iterable indiqué dans l’exemple ci-dessous.

try {
    // your code goes here.
} catch (Exception exception) {

    // Attach some text.
    ErrorAttachmentLog textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt");

    // Attach binary data.
    byte[] binaryData = getYourBinary();
    ErrorAttachmentLog binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg");

    // Track an exception with attachments.
    Crashes.trackError(exception, null, Arrays.asList(textLog, binaryLog));
}
try {
    // your code goes here.
} catch (exception: Exception) {

    // Attach some text.
    val textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt")

    // Attach binary data.
    val binaryData = getYourBinary()
    val binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg")

    // Track an exception with attachments.
    Crashes.trackError(exception, null, listOf(textLog, binaryLog))
}

Signalement d’incidents NDK

Rapports d’incidents

Pour recevoir des rapports d’incident appropriés dans App Center, vérifiez d’abord que le Kit de développement logiciel (SDK) App Center Crashs est configuré en suivant les instructions ci-dessus.

Création de la bibliothèque breakpad

Ensuite, incluez et compilez Google Breakpad en suivant les instructions répertoriées dans le fichier README officiel de Google Breakpad pour Android.

Notes

Le Kit de développement logiciel (SDK) App Center ne regroupe pas Google Breakpad par défaut.

Attachement du gestionnaire d’exceptions

Une fois google breakpad inclus, attachez le gestionnaire d’incident NDK après AppCenter.start:

// Attach NDK Crash Handler after SDK is initialized.
Crashes.getMinidumpDirectory().thenAccept(new AppCenterConsumer<String>() {
    @Override
    public void accept(String path) {

        // Path is null when Crashes is disabled.
        if (path != null) {
            setupNativeCrashesListener(path);
        }
    }
});

La méthode setupNativeCrashesListener est une méthode native que vous devez implémenter en C/C++ :

#include "google-breakpad/src/client/linux/handler/exception_handler.h"
#include "google-breakpad/src/client/linux/handler/minidump_descriptor.h"

void Java_com_microsoft_your_package_YourActivity_setupNativeCrashesListener(
        JNIEnv *env, jobject, jstring path) {
    const char *dumpPath = (char *) env->GetStringUTFChars(path, NULL);
    google_breakpad::MinidumpDescriptor descriptor(dumpPath);
    new google_breakpad::ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1);
    env->ReleaseStringUTFChars(path, dumpPath);
}

dumpCallback est utilisé pour la résolution des problèmes :

/*
 * Triggered automatically after an attempt to write a minidump file to the breakpad folder.
 */
bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor,
                  void *context,
                  bool succeeded) {

    // Allow system to log the native stack trace.
    __android_log_print(ANDROID_LOG_INFO, "YourLogTag",
                        "Wrote breakpad minidump at %s succeeded=%d\n", descriptor.path(),
                        succeeded);
    return false;
}

Une fois ces méthodes correctement configurées, l’application envoie automatiquement le minidump à App Center lors du redémarrage. Pour résoudre les problèmes, vous pouvez utiliser des journaux détaillés (AppCenter.setLogLevel(Log.VERBOSE) avant AppCenter.start) pour case activée si des minidumps sont envoyés après le redémarrage de l’application.

Notes

App Center utilise le nom minidump.dmp réservé pour les pièces jointes minidump. Veillez à donner un nom différent à votre pièce jointe, sauf s’il s’agit d’un fichier minidump afin que nous puissions le gérer correctement.

Notes

Il existe un bogue connu dans le bloc-arrêt qui rend impossible la capture des incidents sur les émulateurs x86.

Symbolique

Pour plus d’informations sur le traitement des incidents, consultez la documentation diagnostics .