/** * Autor: Jakub 'Fiołek' Fijałkowski * http://blog.fiolek.org * Licencja: "róbta co chceta", ale autor nie obrazi się, jak będziecie o nim pamiętać. */ package org.fiolek.utils; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.nio.CharBuffer; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Process; import android.text.Html; import android.text.Spanned; import android.widget.Toast; /** * Zgłaszanie błędu. * * Obsługuje akcje: ACTION_EXCEPTION ACTION_USER */ public class BugReport extends Activity { /** * Wywołane przez niezłapany wyjątek - pytamy, czy chcemy wysłać. */ public static final String ACTION_EXCEPTION = "ACTION_EXCEPTION"; /** * Wywołane przez użytkownika - tworzymy mail bez pytania. */ public static final String ACTION_USER = "ACTION_USER"; private static final String[] EmailAddresses = { "mail@mail.com" }; private static final String MailSubject = "Bug report"; private static final int SendDialog = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent i = this.getIntent(); if (i == null || i.getAction() == null || ACTION_EXCEPTION.equals(i.getAction())) this.OnException(); else if (ACTION_USER.equals(i.getAction())) this.OnUser(); } @Override protected Dialog onCreateDialog(int id) { if (id == SendDialog) return this.CreateDialog(); return null; } /** * Wywoływane przy ACTION_EXCEPTION. */ private void OnException() { this.showDialog(SendDialog); } /** * Przy akcji użytkownika. */ private void OnUser() { this.PrepareMail(); Process.killProcess(Process.myPid()); } /** * Tworzy dialog tak/nie. * * @return */ private Dialog CreateDialog() { return new AlertDialog.Builder(this) .setMessage("Wysłać raport o błędach?").setCancelable(false) .setPositiveButton("Tak", this.SendMail) .setNegativeButton("Nie", this.DoNotSendMail) .create(); } /** * Pobieramy treść wiadomości. * * @return */ private Spanned GetMailContent() { // Ładujemy kod HTML z zasobów InputStream stream = this.getResources().openRawResource(R.raw.bug_report_mail); // TODO: zmienić ścieżkę do pliku HTML InputStreamReader reader = new InputStreamReader(stream); CharBuffer buff = CharBuffer.allocate(1024 * 2); try { reader.read(buff); stream.close(); } catch (IOException e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); } buff.flip(); String content = buff.toString(); // Podmieniamy stałe content = content .replace("[[SDK_INT]]", Integer.toString(Build.VERSION.SDK_INT)) .replace("[[RELEASE]]", Build.VERSION.RELEASE); // Dla ułatwienia tylko iterujemy Field[] fields = Build.class.getFields(); for (Field f : fields) { int m = f.getModifiers(); if ((m & Modifier.STATIC) == Modifier.STATIC && (m & Modifier.FINAL) == Modifier.FINAL && (m & Modifier.PUBLIC) == Modifier.PUBLIC && f.getType() == String.class) { try { content = content.replace("[[" + f.getName() + "]]", (String) f.get(null)); } catch (Exception e) {} } } return Html.fromHtml(content); } /** * Przygotowuje maila. */ private void PrepareMail() { Intent email = new Intent(Intent.ACTION_SEND); email.setType("text/html"); email.putExtra(Intent.EXTRA_EMAIL, EmailAddresses); email.putExtra(Intent.EXTRA_SUBJECT, MailSubject); email.putExtra(Intent.EXTRA_TEXT, this.GetMailContent()); Uri log = null; // Pobieramy URI do loga - to musimy napisać sami - czy to własny logger, czy też odczytywanie logcata if (log != null) email.putExtra(Intent.EXTRA_STREAM, log); // Dodajemy jako załącznik this.startActivity(Intent.createChooser(email, "Wyślij raport za pomocą:")); } /** * Wysyłamy maila. */ private DialogInterface.OnClickListener SendMail = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { PrepareMail(); Process.killProcess(Process.myPid()); } }; /** * Tylko zabijamy aplikację. */ private DialogInterface.OnClickListener DoNotSendMail = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Process.killProcess(Process.myPid()); } }; }