简体   繁体   中英

how to save android studio stacktrace Logs into text file in device internal Storage

Is it possible to Save Android Studio stack trace log into text file in device storage for tracing error and bugs in real device? I want save All Android Studio logs into text programmatically.

How can i implement locally logging system in android Application.

First implement a crash reported for your app, when ever you need to save stack trace, manually create a division by zero crash. When you start your app again, stack trace is available for you. Here the crash reporter displays a dialog and ask user to email the stack trace, you can save it to a file instead of displaying the dialog!

Here is a full explanation for setup your own crash reporter, it will show a dialog like this to the user when your app starts again and asks him/her to send the log with email:

在此处输入图像描述

1- Create a class names UnexpectedCrashSaver:

public class UnexpectedCrashSaver implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler defaultUEH;
private Context app = null;
public UnexpectedCrashSaver(Context app) {
    this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    this.app = app;
}
public void uncaughtException(Thread t, Throwable e) {
    StackTraceElement[] arr = e.getStackTrace();
    String report = e.toString()+"\n\n";
    report += "--------- Stack trace ---------\n\n";
    for (int i=0; i<arr.length; i++) {
        report += "    "+arr[i].toString()+"\n";
    }
    report += "-------------------------------\n\n";
    App.instance().toastShort("saving!");

    report += "--------- Cause ---------\n\n";
    Throwable cause = e.getCause();
    if(cause != null) {
        report += cause.toString() + "\n\n";
        arr = cause.getStackTrace();
        for (int i=0; i<arr.length; i++) {
            report += "    "+arr[i].toString()+"\n";
        }
    }
    report += "-------------------------------\n\n";
    try {
        FileOutputStream trace = app.openFileOutput("stack.trace",
                Context.MODE_PRIVATE);
        trace.write(report.getBytes());
        trace.close();
    } catch(IOException ioe) {
        // ...
    }
    defaultUEH.uncaughtException(t, e);
}
}

2- Add this line to your onCreate() method of Application class:

        Thread.setDefaultUncaughtExceptionHandler(new UnexpectedCrashSaver(this));

if you don't have application class add this code to your onCreate() method of all activities: (if you have BaseActivity just put it in onCreate() method of BaseActivity

Thread.setDefaultUncaughtExceptionHandler(new UnexpectedCrashSaver(ActivityName.this));

3- create a layout named checkbox.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<CheckBox
    android:id="@+id/checkbox"
    style="?android:attr/textAppearanceMedium"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp" />
 </FrameLayout>

4- Add the following method to your MainActivity class:

 private void checkForCrash()
{
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    boolean crash_never_ask_again = preferences.getBoolean("crash_never_ask_again", false);
    if(crash_never_ask_again)//Previously user check the checkbox of never ask me again about sending crash dialog
        return;
    String dialog_message = "In the last run, the program encountered an error, we apologize for this, you can kindly send us the error information to fix this error in future updates.";
    String button_positive_text = "Send";
    String button_negative_text = "Close";
    String checkbox_text = "Never ask again";
    String email = "crashreport@example.com";

    String line;
    String trace="";
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(MainActivity.this.openFileInput("stack.trace")));
        while((line = reader.readLine()) != null) {
            trace += line+"\n";
        }
    } catch(FileNotFoundException fnfe) {
        // ...
    } catch(IOException ioe) {
        // ...
    }
    if(trace.length() < 10)//We didn't have any crash
        return;

    View checkBoxView = View.inflate(this, R.layout.checkbox, null);
    CheckBox checkBox =  checkBoxView.findViewById(R.id.checkbox);
    checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean("checkbox_checked",true);
            editor.apply();
        }
    });
    checkBox.setText(checkbox_text);

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setCancelable(true);
    //builder.setIcon(R.drawable.ic_setting);
    builder.setMessage(dialog_message);
    builder.setView(checkBoxView);
    builder.setCancelable(false);
    String finalTrace = trace;
    builder.setPositiveButton(button_positive_text, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Intent sendIntent = new Intent(Intent.ACTION_SEND);
            String subject = "Error report";
            String body = "Mail this to appdeveloper@gmail.com: " + "\n" + finalTrace + "\n";

            sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {email});
            sendIntent.putExtra(Intent.EXTRA_TEXT, body);
            sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
            sendIntent.setType("message/rfc822");
            MainActivity.this.startActivity(Intent.createChooser(sendIntent, "Title:"));
            MainActivity.this.deleteFile("stack.trace");
        }
    });
    builder.setNegativeButton(button_negative_text, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            MainActivity.this.deleteFile("stack.trace");
            boolean checkbox_checked = preferences.getBoolean("checkbox_checked", false);
            if(checkbox_checked)
            {
                SharedPreferences.Editor editor = preferences.edit();
                editor.putBoolean("crash_never_ask_again",true);
                editor.apply();
            }
                dialog.dismiss();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

}

5- call the method created in step 4 in onCreate method of MainActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    checkForCrash();
    setContentView(R.layout.activity_main);
    //...

Thats all!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM