ATUALIZAÇÃO: consulte a solução "aceita" abaixo
Quando meu aplicativo cria uma exceção não tratada, em vez de simplesmente encerrar, gostaria primeiro de dar ao usuário a oportunidade de enviar um arquivo de log. Percebo que fazer mais trabalho depois de obter uma exceção aleatória é arriscado, mas, ei, o pior é que o aplicativo pára de funcionar e o arquivo de log não é enviado. Isso está se tornando mais complicado do que eu esperava :)
O que funciona: (1) capturar a exceção não detectada, (2) extrair informações de log e gravar em um arquivo.
O que ainda não funciona: (3) iniciar uma atividade para enviar email. No final das contas, terei mais uma atividade para pedir a permissão do usuário. Se eu fizer com que a atividade de e-mail funcione, não espero muitos problemas para o outro.
O ponto crucial do problema é que a exceção não tratada é capturada na minha classe Application. Já que não é uma atividade, não é óbvio como iniciar uma atividade com Intent.ACTION_SEND. Ou seja, normalmente, para iniciar uma atividade, chama-se startActivity e continua com onActivityResult. Esses métodos são suportados por Activity, mas não por Application.
Alguma sugestão de como fazer isso?
Aqui estão alguns recortes de código como um guia inicial:
public class MyApplication extends Application
{
defaultUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler();
public void onCreate ()
{
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
private void handleUncaughtException (Thread thread, Throwable e)
{
String fullFileName = extractLogToFile(); // code not shown
// The following shows what I'd like, though it won't work like this.
Intent intent = new Intent (Intent.ACTION_SEND);
intent.setType ("plain/text");
intent.putExtra (Intent.EXTRA_EMAIL, new String[] {"[email protected]"});
intent.putExtra (Intent.EXTRA_SUBJECT, "log file");
intent.putExtra (Intent.EXTRA_STREAM, Uri.parse ("file://" + fullFileName));
startActivityForResult (intent, ACTIVITY_REQUEST_SEND_LOG);
}
public void onActivityResult (int requestCode, int resultCode, Intent data)
{
if (requestCode == ACTIVITY_REQUEST_SEND_LOG)
System.exit(1);
}
}
fonte
Respostas:
Aqui está a solução completa (quase: omiti o layout da IU e o manuseio dos botões) - derivada de muitos experimentos e vários posts de outros relacionados a problemas que surgiram ao longo do caminho.
Existem várias coisas que você precisa fazer:
Agora, aqui estão os detalhes:
(1 e 2) Manipular uncaughtException, iniciar enviar atividade de registro:
(3) Extrair log (coloquei isso em minha atividade SendLog):
(4) Inicie um aplicativo de e-mail (também em minha atividade SendLog):
(3 e 4) Esta é a aparência do SendLog (no entanto, você terá que adicionar a IU):
(5) Manifesto:
(6) Programa de configuração:
Em project.properties, altere a linha de configuração. Você deve especificar "otimizar" ou o Proguard não removerá as chamadas Log.v () e Log.d ().
Em proguard-project.txt, adicione o seguinte. Isso diz ao Proguard para assumir que Log.v e Log.d não têm efeitos colaterais (embora tenham, já que gravam nos logs) e, portanto, podem ser removidos durante a otimização:
É isso aí! Se você tiver alguma sugestão de melhorias para isso, por favor me avise e eu posso atualizar isto.
fonte
Hoje, existem muitas ferramentas de reprting de falha que fazem isso facilmente.
crashlytics - Uma ferramenta de relatório de falhas, gratuita, mas oferece relatórios básicos Vantagens: Grátis
Gryphonet - Uma ferramenta de relatório mais avançada, requer algum tipo de taxa. Vantagens: Fácil recriação de travamentos, ANR's, lentidão ...
Se você for um desenvolvedor privado, eu sugeriria o Crashlytics, mas se for uma grande organização, eu escolheria a Gryphonet.
Boa sorte!
fonte
Tente usar o ACRA - ele envia o rastreamento da pilha, bem como toneladas de outras informações úteis de depuração, para o seu back-end ou para o documento do Google Docs que você configurou.
https://github.com/ACRA/acra
fonte
A resposta de @PeriHartman funciona bem quando o thread de interface do usuário lança uma exceção não capturada. Fiz algumas melhorias para quando a exceção não capturada é lançada por um thread não IU.
fonte
Bem explicado. Mas uma observação aqui, em vez de gravar em arquivo usando File Writer and Streaming, usei a opção logcat -f diretamente. Aqui está o código
Isso me ajudou a liberar as informações mais recentes do buffer. Usar o streaming de arquivo me deu um problema: não estava liberando os logs mais recentes do buffer. Mas de qualquer maneira, este guia foi realmente útil. Obrigado.
fonte
Lidando com exceções não capturadas: como @gilm explicou, faça isso, (kotlin):
Espero que ajude, funcionou para mim .. (: y). No meu caso, usei a biblioteca 'com.microsoft.appcenter.crashes.Crashes' para rastreamento de erros.
fonte
Você pode lidar com as exceções não detectadas usando a biblioteca FireCrasher e fazer uma recuperação a partir dela.
você pode saber mais sobre a biblioteca neste artigo médio
fonte