1 package jp
.gr
.java_conf
.ofnhwx
.olib
;
3 import java
.io
.BufferedReader
;
5 import java
.io
.FileNotFoundException
;
6 import java
.io
.FileOutputStream
;
7 import java
.io
.FileReader
;
8 import java
.io
.IOException
;
9 import java
.io
.PrintWriter
;
10 import java
.lang
.Thread
.UncaughtExceptionHandler
;
12 import jp
.gr
.java_conf
.ofnhwx
.olib
.utils
.OBitmap
;
13 import android
.app
.Activity
;
14 import android
.app
.ActivityManager
;
15 import android
.app
.ActivityManager
.MemoryInfo
;
16 import android
.app
.AlertDialog
;
17 import android
.content
.ActivityNotFoundException
;
18 import android
.content
.Context
;
19 import android
.content
.DialogInterface
;
20 import android
.content
.DialogInterface
.OnCancelListener
;
21 import android
.content
.DialogInterface
.OnClickListener
;
22 import android
.content
.Intent
;
23 import android
.content
.pm
.PackageInfo
;
24 import android
.content
.pm
.PackageManager
;
25 import android
.content
.pm
.PackageManager
.NameNotFoundException
;
26 import android
.graphics
.Bitmap
;
27 import android
.graphics
.drawable
.BitmapDrawable
;
28 import android
.net
.Uri
;
29 import android
.os
.Build
;
30 import android
.util
.Log
;
31 import android
.widget
.Toast
;
37 public final class ErrorReporter
implements UncaughtExceptionHandler
{
39 private static final String TAG
= ErrorReporter
.class.getSimpleName();
41 private static final UncaughtExceptionHandler DEFAULT_HANDLER
= Thread
.getDefaultUncaughtExceptionHandler();
42 private static final String ERROR_FILE
= "BUG";
43 private static final String REPORT_FILE
= "REPORT";
44 private static Context sContext
= null;
45 private static PackageInfo sPackageInfo
= null;
48 * バグ報告の準備、各Activityのなるべく早い段階で呼び出すこと.
49 * @param context 基本的には{@code this}を指定
51 public static void initialize(Context context
) {
54 if (sContext
!= null) {
59 sContext
= context
.getApplicationContext();
61 PackageManager pm
= sContext
.getPackageManager();
62 sPackageInfo
= pm
.getPackageInfo(sContext
.getPackageName(), 0);
63 } catch (NameNotFoundException e
) {
66 Thread
.setDefaultUncaughtExceptionHandler(new ErrorReporter());
71 * エラー報告の確認を行うダイアログを表示する.
72 * @param activity ダイアログを表示するアクティビティ
73 * @param dialogId 表示するダイアログの{@code id}
75 public static final void show(Activity activity
, int dialogId
) {
76 File file
= activity
.getFileStreamPath(ERROR_FILE
);
80 activity
.showDialog(dialogId
);
84 * エラー報告の確認を行うダイアログを取得する.
89 public static final AlertDialog
getDialog(final Activity activity
, int icon
) {
92 final File file
= activity
.getFileStreamPath(ERROR_FILE
);
95 float density
= activity
.getResources().getDisplayMetrics().density
;
96 Bitmap bitmap
= OBitmap
.decodeResource(activity
, icon
, (int)(32 * density
));
99 AlertDialog
.Builder dialog
= new AlertDialog
.Builder(activity
);
100 dialog
.setIcon(new BitmapDrawable(bitmap
));
101 dialog
.setTitle(R
.string
.bug_report_title
);
102 dialog
.setMessage(R
.string
.bug_report_message
);
105 dialog
.setPositiveButton(R
.string
.bug_report_positive
, new OnClickListener() {
106 public void onClick(DialogInterface dialog
, int which
) {
107 sendBugreport(activity
, file
);
112 dialog
.setNegativeButton(R
.string
.bug_report_negative
, new OnClickListener() {
113 public void onClick(DialogInterface dialog
, int which
) {
114 if (!file
.delete()) {
115 Log
.e(TAG
, "Couldn't delete error file.");
121 dialog
.setOnCancelListener(new OnCancelListener() {
122 public void onCancel(DialogInterface dialog
) {
123 if (!file
.delete()) {
124 Log
.e(TAG
, "Couldn't delete error file.");
130 return dialog
.create();
138 * @throws IOException
140 private static final void sendBugreport(Context context
, File errorFile
) {
143 File file
= context
.getFileStreamPath(REPORT_FILE
);
144 if (!errorFile
.exists() || !errorFile
.renameTo(file
)) {
149 BufferedReader reader
;
151 reader
= new BufferedReader(new FileReader(file
));
152 } catch (FileNotFoundException e
) {
159 StringBuilder text
= new StringBuilder();
161 subject
= reader
.readLine();
162 text
.append(subject
).append("\n");
164 while ((line
= reader
.readLine()) != null) {
165 text
.append(line
).append("\n");
167 } catch (IOException e
) {
170 try { reader
.close(); } catch (Exception e
) {}
171 if (!file
.delete()) {
172 Log
.e(TAG
, "Can't delete report file.");
177 String
[] mail
= new String
[] { context
.getString(R
.string
.mail
) };
178 Intent intent
= new Intent();
179 intent
.setAction(Intent
.ACTION_SEND
);
180 intent
.setType("message/rfc822");
181 intent
.putExtra(Intent
.EXTRA_EMAIL
, mail
);
182 intent
.putExtra(Intent
.EXTRA_SUBJECT
, subject
);
183 intent
.putExtra(Intent
.EXTRA_TEXT
, text
.toString());
185 context
.startActivity(intent
);
186 } catch (ActivityNotFoundException e
) {
187 String mailTo
= context
.getString(R
.string
.mail_to
);
188 intent
= new Intent(Intent
.ACTION_SENDTO
, Uri
.parse(mailTo
));
189 intent
.putExtra(Intent
.EXTRA_SUBJECT
, subject
);
190 intent
.putExtra(Intent
.EXTRA_TEXT
, text
.toString());
192 context
.startActivity(intent
);
193 } catch (ActivityNotFoundException e2
) {
194 Toast
.makeText(context
, "Activity not found.", Toast
.LENGTH_SHORT
).show();
203 public void uncaughtException(Thread thread
, Throwable error
) {
206 error
.printStackTrace();
211 FileOutputStream fos
= sContext
.openFileOutput(ERROR_FILE
, Context
.MODE_WORLD_READABLE
);
212 writer
= new PrintWriter(fos
);
213 } catch (FileNotFoundException e
) {
214 // ここには到達しない、しても何もしない
219 if (sPackageInfo
!= null) {
220 writer
.printf("[BUG][%s] versionName:%s, versionCode:%d\n",
221 sPackageInfo
.packageName
,
222 sPackageInfo
.versionName
,
223 sPackageInfo
.versionCode
);
225 writer
.printf("[BUG][Unkown Package]\n");
228 // メモリ情報の記録(Total, Free, Used)
229 long total
= Runtime
.getRuntime().totalMemory() / 1024;
230 long free
= Runtime
.getRuntime().freeMemory() / 1024;
231 writer
.printf("Runtime Memory: total: %dKB, free: %dKB, used: %dKB\n",
232 total
, free
, total
- free
);
234 // メモリ情報の記録(Avail, LowMemory)
235 ActivityManager am
= (ActivityManager
)sContext
.getSystemService(Context
.ACTIVITY_SERVICE
);
236 MemoryInfo info
= new MemoryInfo();
237 am
.getMemoryInfo(info
);
238 writer
.printf("availMem: %dKB, lowMemory: %b\n",
239 info
.availMem
/ 1024, info
.lowMemory
);
242 writer
.printf("DEVICE: %s\n", Build
.DEVICE
);
243 writer
.printf("MODEL : %s\n", Build
.MODEL
);
244 writer
.printf("VERSION.SDK: %s\n", Build
.VERSION
.SDK
);
248 error
.printStackTrace(writer
);
254 DEFAULT_HANDLER
.uncaughtException(thread
, error
);