App Center のクラッシュ (Android)

重要

Visual Studio App Center は、2025 年 3 月 31 日に廃止される予定です。 完全に廃止されるまで Visual Studio App Center を引き続き使用できますが、移行を検討できる推奨される代替手段がいくつかあります。

詳細については、サポートタイムラインと代替手段に関するページを参照してください。

App Center のクラッシュでは、アプリがクラッシュするたびにクラッシュ ログが自動的に生成されます。 ログは最初にデバイスのストレージに書き込まれ、ユーザーがアプリを再度起動すると、クラッシュ レポートが App Center に送信されます。 クラッシュの収集は、ベータアプリとライブアプリの両方、つまりGoogle Playに送信されたアプリの両方で機能します。 クラッシュ ログには、クラッシュの修正に役立つ貴重な情報が含まれています。

アプリケーションで SDK をまだ設定していない場合は、はじめにセクションに従います。

テスト クラッシュを生成する

App Center のクラッシュには、SDK を簡単にテストするためのテスト クラッシュを生成する API が用意されています。 この API はデバッグ ビルドでのみ使用でき、リリース ビルドでは何も行いません。

Crashes.generateTestCrash();
Crashes.generateTestCrash()

以前のクラッシュに関する詳細情報を取得する

App Center のクラッシュには、アプリがクラッシュした場合に備えて詳細情報を提供する 2 つの API があります。

アプリは前のセッションでメモリ不足の警告を受け取りましたか?

SDK を起動した後は、いつでも、アプリが前のセッションでメモリ警告を受け取ったかどうかをチェックできます。

Crashes.hasReceivedMemoryWarningInLastSession();
Crashes.hasReceivedMemoryWarningInLastSession()

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

注意

このメソッドは、開始後 Crashes にのみ使用する必要があり、常に開始前に戻ります false

注意

場合によっては、メモリが不足しているデバイスでイベントを送信できない場合があります。

前のセッションでアプリがクラッシュしましたか?

SDK を起動した後は、いつでも、前の起動でアプリがクラッシュした場合にチェックできます。

Crashes.hasCrashedInLastSession();
Crashes.hasCrashedInLastSession()

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

これは、クラッシュが発生した後にアプリの動作または UI を調整する場合に便利です。 一部の開発者は、ユーザーに対して謝るために追加の UI を表示するか、クラッシュが発生した後に連絡を取る方法を選択しました。

注意

このメソッドは、開始後 Crashes にのみ使用する必要があり、常に開始前に戻ります false

最後のクラッシュの詳細

アプリが以前にクラッシュした場合は、最後のクラッシュに関する詳細を取得できます。

Crashes.getLastSessionCrashReport();
Crashes.getLastSessionCrashReport()

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

この API には多くのユース ケースがあります。最も一般的なのは、この API を呼び出し、カスタム の CrashesListener を実装するユーザーです。

注意

このメソッドは、開始後 Crashes にのみ使用する必要があり、常に開始前に戻ります null

App Center のクラッシュの使用をカスタマイズする

App Center のクラッシュは、クラッシュ ログを App Center に送信する前と送信する際に、開発者が追加のアクションを実行するためのコールバックを提供します。

コールバックを処理するには、インターフェイス内のすべてのメソッドを CrashesListener 実装するか、 クラスを AbstractCrashesListener オーバーライドして、関心のあるメソッドのみを選択します。

独自の CrashesListener を使用する

独自の CrashesListener を作成し、次のように割り当てます。

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

一部のコールバックのカスタマイズにのみ関心がある場合は、代わりに を AbstractCrashesListener 使用します。

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)

注意

App Center が開始直後 クラッシュする処理を開始するため、 を呼び出す AppCenter.start()前にリスナーを設定します。

クラッシュを処理する必要がありますか?

特定のクラッシュを処理する必要があるかどうかを判断する場合は、このコールバックを実装します。 たとえば、無視する必要があり、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
}

ユーザーのプライバシーが重要な場合は、クラッシュ レポートを App Center に送信する前にユーザーの確認を受け取る必要があります。 SDK は、クラッシュ レポートを送信する前にユーザーの確認を待機するように App Center クラッシュに指示するコールバックを公開します。

これを選択した場合は、ユーザーの確認を取得する必要があります。たとえば、ダイアログ プロンプトで次のいずれかのオプションを使用します。 Always SendSendDon't send。 入力に基づいて、App Center のクラッシュに何をすべきかを伝え、クラッシュはそれに応じて処理されます。

注意

SDK ではこれに対するダイアログは表示されません。アプリは、ユーザーの同意を求めるために独自の UI を提供する必要があります。

次のコールバックは、クラッシュを送信する前にユーザーの確認を待機するように SDK に指示する方法を示しています。

@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
}

を返す true場合、アプリはユーザーのアクセス許可を取得し (独自のコードを使用して)、次の API を使用して結果を SDK にメッセージする必要があります。

// 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)

例として、 カスタム ダイアログの例を参照できます。

クラッシュ ログの送信状態に関する情報を取得する

アプリのクラッシュの状態を知りたい場合があります。 一般的なユース ケースは、アプリがクラッシュ レポートを送信していることをユーザーに伝える UI を表示する場合や、アプリが起動後にすぐにクラッシュする場合は、クラッシュ ログを送信できるようにアプリの動作を調整する必要がある場合です。 App Center のクラッシュには、アプリで何が起こっているかを通知するために使用できる 3 つの異なるコールバックがあります。

SDK がクラッシュ ログを送信する前に、次のコールバックが呼び出されます

@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.
}

エンドポイントでネットワークの問題や停止が発生し、アプリを再起動した場合は、 onBeforeSending プロセスの再起動後に再度トリガーされます。

SDK がクラッシュ ログを正常に送信した後、次のコールバックが呼び出されます

@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.
}

SDK がクラッシュ ログを送信できなかった場合は、次のコールバックが呼び出されます

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

onSendingFailed受信とは、4xx コードが発生したなどの回復不可能なエラーを意味します。 たとえば、 401 は が appSecret 間違っていることを意味します。

このコールバックは、ネットワークの問題である場合はトリガーされません。 この場合、SDK は再試行を続けます (また、ネットワーク接続がダウンしている間も再試行を一時停止します)。

クラッシュ レポートに添付ファイルを追加する

バイナリ添付ファイルとテキスト添付ファイルをクラッシュ レポートに追加できます。 SDK によってクラッシュと共に送信されるため、App Center ポータルで確認できます。 次のコールバックは、以前のアプリケーションの起動から格納されたクラッシュを送信する直前に呼び出されます。 クラッシュが発生しても呼び出されません。 その名前はミニダンプ ファイル用に予約されているため、添付ファイルの名前minidump.dmp付いていないことを確認してください。 テキストと画像をクラッシュに添付する方法の例を次に示します。

@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)
}

注意

現在、サイズ制限は 7 MB です。 より大きな添付ファイルを送信しようとすると、エラーが発生します。

実行時に App Center のクラッシュを有効または無効にする

実行時に App Center のクラッシュを有効または無効にすることができます。 無効にした場合、SDK はアプリのクラッシュ レポートを実行しません。

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

App Center のクラッシュを再度有効にするには、同じ API を使用しますが、 パラメーターとして を渡 true します。

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

状態は、アプリケーションの起動間でデバイスのストレージに保持されます。

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

注意

このメソッドは、開始後 Crashes にのみ使用する必要があります。

App Center のクラッシュが有効になっているかどうかを確認する

App Center のクラッシュが有効になっているかどうかをチェックすることもできます。

Crashes.isEnabled();
Crashes.isEnabled()

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

注意

このメソッドは、開始後 Crashes にのみ使用する必要があります。常に開始前にが返 false されます。

処理されたエラー

App Center では、処理された例外を使用してエラーを追跡することもできます。 これを行うには、 メソッドを使用します trackError

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

アプリは必要に応じて、処理されたエラー レポートにプロパティを添付して、さらにコンテキストを提供できます。 次の例に示すように、キーと値のペア (文字列のみ) のマップとしてプロパティを渡します。

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)
}

必要に応じて、処理されたエラー レポートにバイナリ添付ファイルとテキスト添付ファイルを追加することもできます。 次の例に Iterable 示すように、添付ファイルを として渡します。

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))
}

NDK のクラッシュの報告

クラッシュの報告

App Center で適切なクラッシュ レポートを受信するには、まず、上記の手順に従って App Center Crashs SDK が設定されていることを確認します。

ブレークパッド ライブラリのビルド

次に、公式の Google Breakpad for Android README に記載されている手順に従って 、Google Breakpad を含めてコンパイルします。

注意

App Center SDK では、既定では Google Breakpad はバンドルされません。

例外ハンドラーのアタッチ

Google Breakpad を含んだら、 の後 AppCenter.startに NDK クラッシュ ハンドラーをアタッチします。

// 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);
        }
    }
});

メソッド setupNativeCrashesListener は、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 トラブルシューティングに使用されます。

/*
 * 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;
}

これらのメソッドが適切に設定されると、アプリは再起動時にミニダンプを App Center に自動的に送信します。 トラブルシューティングを行うには、詳細ログ (AppCenter.setLogLevel(Log.VERBOSE) の前AppCenter.start) を使用して、アプリの再起動後にミニダンプが送信されるかどうかをチェックできます。

注意

App Center では、ミニダンプの添付ファイルに予約名 minidump.dmp が使用されます。 添付ファイルがミニダンプ ファイルでない限り、添付ファイルに別の名前を付けて、適切に処理できるようにします。

注意

ブレークパッドには既知のバグがあり、x86 エミュレーターでクラッシュをキャプチャできなくなります。

シンボリック化

クラッシュの処理の詳細については、診断に関する ドキュメントを参照してください