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.
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()
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.
À 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.
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.
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.
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.
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é.
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 :
@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.
@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.
}
@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).
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.
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.
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.
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))
}
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.
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.
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);
}
Où 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.
Pour plus d’informations sur le traitement des incidents, consultez la documentation diagnostics .