I have an application for android that I test wherever possible and on some devices the application crashes, but I don’t have these devices at hand, and I accordingly need something to send me error messages in the mail. I already asked two questions. Determine the cause of the application crash on the android phone // Incomprehensible problem of the android y xiaomi program . And here I had a logical question: what do I need to add to my application, so that during the fall it suggested the user to send logs to me in the mail? How to do this so that these log tracking methods are activated only when the application crashes and not in any case (methods) convenient for them. I will be very grateful for any help, advice and self-criticism from all who see my question. Thanks in advance for your help.

2 answers 2

I wrote such a class for our game:

public class LogsSender { public static void sendLogs(Activity activity) { Log("sendLogs" ); printInfo(); int pid = android.os.Process.myPid(); try { String command = String.format("logcat -d -v threadtime *:*"); Process process = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder result = new StringBuilder(); String currentLine = null; while ((currentLine = reader.readLine()) != null) { if (currentLine != null && currentLine.contains(String.valueOf(pid))) { result.append(currentLine); result.append("\n"); } } Log(result.toString()); Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); emailIntent.setType("vnd.android.cursor.item/email"); emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"ваша_почта"}); emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Logs"); emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, result.toString()); activity.startActivity(Intent.createChooser(emailIntent, "Send mail using...")); } catch (Exception e) { e.printStackTrace(); } } private static void Log(String txt){ Log.d("unity", txt); } private static void printInfo(){ Log("externalMemoryAvailable: " + externalMemoryAvailable()); if(externalMemoryAvailable()){ Log("getTotalExternalMemorySize: " + getTotalExternalMemorySize()); Log("getAvailableExternalMemorySize: " + getAvailableExternalMemorySize()); } Log("getTotalInternalMemorySize: " + getTotalInternalMemorySize()); Log("getAvailableInternalMemorySize: " + getAvailableInternalMemorySize()); } private static boolean externalMemoryAvailable() { return android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); } private static String getAvailableInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long availableBlocks = stat.getAvailableBlocksLong(); return formatSize(availableBlocks * blockSize); } private static String getTotalInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long totalBlocks = stat.getBlockCountLong(); return formatSize(totalBlocks * blockSize); } private static String getAvailableExternalMemorySize() { if (externalMemoryAvailable()) { File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long availableBlocks = stat.getAvailableBlocksLong(); return formatSize(availableBlocks * blockSize); } else { return "ext not available"; } } private static String getTotalExternalMemorySize() { if (externalMemoryAvailable()) { File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSizeLong(); long totalBlocks = stat.getBlockCountLong(); return formatSize(totalBlocks * blockSize); } else { return "ext not available"; } } private static String formatSize(long size) { String suffix = null; if (size >= 1024) { suffix = "KB"; size /= 1024; if (size >= 1024) { suffix = "MB"; size /= 1024; } } StringBuilder resultBuffer = new StringBuilder(Long.toString(size)); int commaOffset = resultBuffer.length() - 3; while (commaOffset > 0) { resultBuffer.insert(commaOffset, ','); commaOffset -= 3; } if (suffix != null) resultBuffer.append(suffix); return resultBuffer.toString(); } } 

If you need crash logs, then the LoginActivity code that causes LoginActivity can be wrapped in try {} catch{} , in catch output exceptions to the log and then call LogsSender.sendLogs . A window will open with a choice of mail client, automatically all fields will be entered after a client is selected. A person will only have to click the "Send" button.

    Honestly, I have not tried yet to implement the code given in the first answer, while no one answered me, I found this way on the network:

      @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(activity_login); submitBtn = findViewById(R.id.btn_submit); submitBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sendPost(); } }); Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable ex) { handleUncaughtException(thread, ex); } }); } public void handleUncaughtException (Thread thread, Throwable e) { String stackTrace = Log.getStackTraceString(e); String message = e.getMessage(); Intent intent = new Intent (Intent.ACTION_SEND); intent.setType("message/rfc822"); intent.putExtra (Intent.EXTRA_EMAIL, new String[] {"angoran16@gmail.com"}); intent.putExtra (Intent.EXTRA_SUBJECT, "MyApp Crash log file"); intent.putExtra (Intent.EXTRA_TEXT, stackTrace); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // required when starting from Application startActivity(intent); } 

    This method allowed me to send from the problem phone not by mail, but through any application that has the function of sending messages, telegrams or gmail. In short, this method has helped me at the moment to send the error code and now I have a reason for the crash. I hope my answer will help someone else with a similar problem.