ACRAを使ってアプリのクラッシュ情報を自動送信する


ACRA(Application Crash Report for Android)とは、Androidアプリがクラッシュしたときに、アプリがどのような環境と状況でクラッシュしてしまったかというレポートを開発者に知らせるためのライブラリです。

ACRAを利用することで開発者はAndroid Marketに公開後、ユーザがアプリを利用中に発生したクラッシュの原因を詳細に得ることができるようになります。

ACRAでは開発者に知らせる手段として幾つか選択肢が用意されています。

[table “216” not found /]

今回はGoogle Docsへクラッシュレポートを送信する手順について解説したいと思います。
詳しい解説は続きからご覧下さい。

ライブラリはRCRAのプロジェクトサイトに公開されています。

利用までの手順としては以下の通りです。

  • ライブラリの入手
  • Google Docsの準備
  • ライブラリのコピー
  • ライブラリのインポート
  • クラスファイルの追加とマニフェストファイルの修正

ライブラリの入手

ARCAプロジェクトサイト上のDownloadsページからライブラリをダウンロードします。
2012/03/07現在、バージョン4.2.3が最新となっています。

ダウンロードしたzipファイルを展開するとライブラリを構成するjarファイルの他、java docやクラッシュレポートのためのテンプレートなどが現れます。

[table “217” not found /]

Google Docsの準備

次にレポートの送信先となるGoogle Docsの準備を行います。
※Google Docsのログイン方法など、Google Docs自体の基本的な使い方についてはここでは解説を割愛します。

Google Docsの画面左にあるアップロードアイコンから、さきほど展開したCrashReports-Template.csvをアップロードします。
このファイルはクラッシュレポートのテンプレートになります。

アップロード時、Google Docsフォーマットへの変換の設定が表示されますが、そのままの設定で問題ありません。

アップロードが完了したらアップロードしたクラッシュレポートを開きます。
開いたGoogle Docsの画面上にある「ツール」メニューから「フォーム」→「フォームを作成」を開いて下さい。

フォームの作成画面上の「説明文」の入力欄にフォームの概要を入力し、「保存」を押します。
また、この画面の下に下記のようなURLが表示されているはずです。

formkey=以降の文字列はあとでアプリ上から指定することに成りますので、ここで控えておきます。

ライブラリのコピー

自分のプロジェクトにライブラリをコピーします。
プロジェクトのディレクトリに「libs」ディレクトリを作成し、そこにさきほどのacra-4.2.3.jarファイルをコピーします。

ライブラリのインポート

ライブラリのインポートはEclipseで行います。
Eclipseのパッケージエクスプローラ上でプロジェクトを指定して右クリックし、「Build Path」→「Add External Archives」を開きます。

この画面から外部ライブラリをインポートすることができるので、さきほどlibsディレクトリ上にコピーしたacra-4.2.3.jarを指定します。

クラスの追加

次にプロジェクトに1つクラスを追加します。
名前は何でも良いですが、ここでは仮にMyApplicationという名前にします。
ここでandroid.app.Applicationクラスを継承して作成するようにしてください。

import org.acra.*;
import org.acra.annotation.*;

@ReportsCrashes(formKey = "YOUR_FORMKEY")
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        // The following line triggers the initialization of ACRA
        ACRA.init(this);
        super.onCreate();
    }
}

4行目のformkeyの値に先ほどGoogle Docsのフォーム画面で取得した文字列を指定します。
9行目のonCreate内にACRA.init()を実行して、ACRAライブラリを初期化します。

次にManifestファイルを編集します。

<application android:icon="@drawable/icon" android:label="@string/app_name"
                android:name="MyApplication">

Google Docsへレポート送信時、インターネットを利用することになりますのでandroid.permission.INTERNETパーミッションを追加します。

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

以上で設定は完了です。

動作確認

では実際にアプリをクラッシュさせてレポートがGoogle Docsに送信されるか確認してみましょう。

実験用のソースコードとして配列のサイズ外の領域にアクセスしてArrayIndexOutOfBoundsExceptionエラーを発生させるようにしてみます。

package org.techbooster;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class AcraDemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        int[] array = {1, 2, 3, 4, 5};
        for (int i=0; i<array.length+1; i++)
        	Log.i("AcraDemoActivity", "value:"+array[i]);
    }
}

実行すると以下のようにアプリがクラッシュし、強制終了のダイアログが表示されます。

ここでGoogle Docsを確認するとレポートが送信されています。

情報量が多く見辛いのですが、たとえばトレースログを抜粋すると以下のような情報が取得できます。

"java.lang.RuntimeException: Unable to start activity ComponentInfo{org.techbooster/org.techbooster.AcraDemoActivity}: java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
	at android.app.ActivityThread.access$600(ActivityThread.java:123)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at android.app.ActivityThread.main(ActivityThread.java:4424)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
	at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
	at org.techbooster.AcraDemoActivity.onCreate(AcraDemoActivity.java:17)
	at android.app.Activity.performCreate(Activity.java:4465)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
	... 11 more
java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
	at org.techbooster.AcraDemoActivity.onCreate(AcraDemoActivity.java:17)
	at android.app.Activity.performCreate(Activity.java:4465)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
	at android.app.ActivityThread.access$600(ActivityThread.java:123)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at android.app.ActivityThread.main(ActivityThread.java:4424)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
	at dalvik.system.NativeStart.main(Native Method)
"

上記のように、ACRAを使うとまるでUSBケーブルを繋いでデバッグするかのように詳細なクラッシュレポートを得ることができるようになります。
アプリの品質を高める手段としてACRAは強力な手段と言えるでしょう。

ただし、ユーザの個人情報を自動送信してしまうことになるため、ACRAを実際に利用するときには
アプリのインストール時に自動送信の同意を得るためのダイアログを表示するなど対応が必要です。