コジオニルク - Android - 独自のバグレポート機能とかを参考に
独自クラッシュレポート送信機能を実装してみた。
[Android]Logクラスをもっと使いやすく!クラス名、メソッド名、行数を表示するLogUtilクラス | DevAchieveのクラスにスタックトレースからクラス名、メソッド名、行数を取得する処理を依存しています。
/** * キャッチされなかったExceptionが発生した場合にログを記録する * * @author wada * */ public final class CrashExceptionHandler implements UncaughtExceptionHandler { public static final String FILE_NAME = "report.txt"; public static final String MAILTO = "my.mail@address.com"; private final Context mContext; private final PackageInfo mPackageInfo; private final UncaughtExceptionHandler mHandler; public CrashExceptionHandler(Context context) { mContext = context; try{ mPackageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); }catch(NameNotFoundException e){ throw new RuntimeException(e); } mHandler = Thread.getDefaultUncaughtExceptionHandler(); } /** * キャッチされなかった例外発生時に各種情報をJSONでテキストファイルに書き出す */ @Override public void uncaughtException(Thread thread, Throwable throwable){ PrintWriter writer = null; try{ FileOutputStream outputStream = mContext.openFileOutput(FILE_NAME, Context.MODE_PRIVATE); writer = new PrintWriter(outputStream); JSONObject json = new JSONObject(); json.put("Build", getBuildInfo()); json.put("PackageInfo", getPackageInfo()); json.put("Exception", getExceptionInfo(throwable)); json.put("SharedPreferences", getPreferencesInfo()); writer.print(json.toString()); }catch(FileNotFoundException e){ e.printStackTrace(); }catch(JSONException e){ e.printStackTrace(); }finally{ if(writer != null){ writer.close(); } } mHandler.uncaughtException(thread, throwable); } /** * ビルド情報をJSONで返す * * @return * @throws JSONException */ private JSONObject getBuildInfo() throws JSONException{ JSONObject buildJson = new JSONObject(); buildJson.put("BRAND", Build.BRAND); // キャリア、メーカー名など(docomo) buildJson.put("MODEL", Build.MODEL); // ユーザーに表示するモデル名(SO-01C) buildJson.put("DEVICE", Build.DEVICE); // デバイス名(SO-01C) buildJson.put("MANUFACTURER", Build.MANUFACTURER); // 製造者名(Sony Ericsson) buildJson.put("VERSION.SDK_INT", Build.VERSION.SDK_INT); // フレームワークのバージョン情報(10) buildJson.put("VERSION.RELEASE", Build.VERSION.RELEASE); // ユーザーに表示するバージョン番号(2.3.4) return buildJson; } /** * パッケージ情報を返す * * @return * @throws JSONException */ private JSONObject getPackageInfo() throws JSONException{ JSONObject packageInfoJson = new JSONObject(); packageInfoJson.put("packageName", mPackageInfo.packageName); packageInfoJson.put("versionCode", mPackageInfo.versionCode); packageInfoJson.put("versionName", mPackageInfo.versionName); return packageInfoJson; } /** * 例外情報を返す * * @param throwable * @return * @throws JSONException */ private JSONObject getExceptionInfo(Throwable throwable) throws JSONException{ JSONObject exceptionJson = new JSONObject(); exceptionJson.put("name", throwable.getClass().getName()); exceptionJson.put("cause", throwable.getCause()); exceptionJson.put("message", throwable.getMessage()); // StackTrace JSONArray stackTrace = new JSONArray(); for(StackTraceElement element : throwable.getStackTrace()){ stackTrace.put("at " + LogUtil.getMetaInfo(element)); } exceptionJson.put("stacktrace", stackTrace); return exceptionJson; } /** * Preferencesを返す * * @return * @throws JSONException */ private JSONObject getPreferencesInfo() throws JSONException{ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); JSONObject preferencesJson = new JSONObject(); Map<String, ?> map = preferences.getAll(); for(Entry<String, ?> entry : map.entrySet()){ preferencesJson.put(entry.getKey(), entry.getValue()); } return preferencesJson; } }呼び出しは1アプリにつき1回で良いらしいです。
Thread.setDefaultUncaughtExceptionHandler(new CrashExceptionHandler(getApplicationContext()));
[Android]独自クラッシュレポート送信機能を実装する レポート送信編 | DevAchieveに続く。