Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ACRA 4.9.0 : How can I write ACRA report to file (in Application data folder)

I want to write the crash report in text file using latest Acra 4.9.0. I can,t example for this latest version. I tried using available documentation.

Acra is enabled but it,s not writing in the file.

myApp

 package com.myApp;

import org.acra.ACRA;

import android.app.AlertDialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.KeyEvent;
import android.view.View;

import com.myApp.Application.AppLauncher;
import com.myApp.interfaces.AppEvents;
import com.myApp.R;
import com.utils.Config;
import com.utils.Constants;
import com.utils.DeviceValidator;

public class myApp extends FragmentActivity
{
    private AppLauncher appLauncher = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);

        if(!ACRA.isACRASenderServiceProcess())
        {
            setContentView(R.layout.activity_myApp);

            appLauncher = new AppLauncher();

            appLauncher.registerEventListener(appEventsListener);

            appLauncher.initApp(this);

        }
    }

    @Override
    public void onPause() {
        super.onPause();

        if(!DeviceValidator.isDeviceValid())
        {
            return;
        }

        appLauncher.activityOnPause();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
    }

    @Override
    protected void onStart() 
    {
        super.onStart();
    }

    @Override
    public void onResume()
    {
        super.onResume();

        appLauncher.activityOnResume();
    }
}

AcraApplication

    package com.myAPP;

    import org.acra.ACRA;
    import org.acra.ReportField;
    import org.acra.ReportingInteractionMode;
    import org.acra.annotation.ReportsCrashes;
    import org.acra.sender.HttpSender.Method;

    import android.app.Application;

    @ReportsCrashes(
            formUri = "http://staging.jemtv.com/variable_dump/index.php",
            customReportContent = { ReportField.REPORT_ID, ReportField.DEVICE_ID, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.STACK_TRACE, ReportField.CUSTOM_DATA, ReportField.LOGCAT },
            httpMethod = Method.POST,
            reportSenderFactoryClasses = org.acra.util.MyOwnSenderFactory.class,
            mode = ReportingInteractionMode.SILENT
    )

    public class AcraApplication extends Application
    {
        public AcraApplication() 
        {
            super();
        }

        @Override
        public void onCreate() {
            super.onCreate();
            ACRA.init(this);
        }

    }

MyOwnSender

package org.acra.util;

import java.io.File;
import java.io.FileOutputStream;

import org.acra.ReportField;
import org.acra.collector.CrashReportData;
import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderException;

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

public class MyOwnSender implements ReportSender  {
    private static final String FILE_NAME = "AcraReport.txt";
    //private final Map<ReportField, String> mMapping = new HashMap<ReportField, String>();
    //private FileWriter crashReport = null;

    MyOwnSender(Context context,  @NonNull ACRAConfiguration config)
    {
        Log.d("testAcra", "MyOwnSender created");
       /* File logFile = new File(context.getFilesDir().getPath() + "/" + FILE_NAME, FILE_NAME);

        try {
            crashReport = new FileWriter(logFile, true);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
    }

    @Override
    public void send(Context context, CrashReportData report) throws ReportSenderException
    {
            // Iterate over the CrashReportData instance and do whatever
            // you need with each pair of ReportField key / String value

         String finalReport = createCrashReport(report);
         String tempFile = context.getFilesDir().getPath() + "/" + FILE_NAME;

        try
        {            
            File detailedFile = new File(tempFile); 

            if(!detailedFile.exists())
                detailedFile.createNewFile();

            FileOutputStream stream = new FileOutputStream(detailedFile, true);

            stream.write(finalReport.getBytes());
            Log.d("testAcra","adding to file: "+stream);
            stream.close();

           }
       catch (Exception e)
       { 

        e.printStackTrace(); 
       }
     /*final Map<String, String> finalReport = remap(report);

         try {
             BufferedWriter buf = new BufferedWriter(crashReport);

             Set<Entry<String, String>> set = reportBody.entrySet();
             Iterator<Entry<String, String>> i = set.iterator();

             while (i.hasNext()) {
                 Map.Entry<String, String> me = (Entry<String, String>) i.next();
                 buf.append("[" + me.getKey() + "]=" + me.getValue());
             }

             buf.flush();
             buf.close();
         } catch (IOException e) {
             Log.e("TAG", "IO ERROR", e);
         }*/
    }

    private String createCrashReport(CrashReportData crashReportData){
        StringBuilder body = new StringBuilder();

        body.append("ReportID : " + crashReportData.getProperty(ReportField.REPORT_ID))
                .append("\n")
                .append("DeviceID : " + crashReportData.getProperty(ReportField.DEVICE_ID))
                .append("\n")
                .append("AppVersionName : " + crashReportData.getProperty(ReportField.APP_VERSION_NAME))
                .append("\n")
                .append("Android Version : " + crashReportData.getProperty(ReportField.ANDROID_VERSION))
                .append("\n")
                .append("CustomData : " + crashReportData.getProperty(ReportField.CUSTOM_DATA))
                .append("\n")
                .append("STACK TRACE : \n" + crashReportData.getProperty(ReportField.STACK_TRACE))
                .append("\n")
                .append("LogCAT : \n" + crashReportData.getProperty(ReportField.LOGCAT));

        return body.toString();
    }

 /*   private Map<String, String> remap(Map<ReportField, String> report) {

       Set<ReportField>fields = ACRA.getConfig().getReportFields();


        final Map<String, String> finalReport = new HashMap<String, String>(report.size());
        for (ReportField field : fields)
        {
            if (mMapping == null || mMapping.get(field) == null) 
                finalReport.put(field.toString(), report.get(field));
             else 
                finalReport.put(mMapping.get(field), report.get(field));
        }
        return finalReport;
    }*/
}

MyOwnSenderFactory

package org.acra.util;

import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderFactory;

import android.content.Context;
import android.support.annotation.NonNull;

public class MyOwnSenderFactory implements ReportSenderFactory {

     // NB requires a no arg constructor.
    /*MyOwnSenderFactory()
    {
         Log.e("testAcra", "MyOwnSenderFactory created");
    }*/

    @Override
    @NonNull
    public ReportSender create(@NonNull Context context, @NonNull ACRAConfiguration config) {
        // TODO Auto-generated method stub
        return new MyOwnSender(context, config);
    }
}
like image 763
Usman Hashmi Avatar asked Sep 06 '16 11:09

Usman Hashmi


2 Answers

Because i was using jar file instead of aar in my manifest i was missing

 <service
            android:name="org.acra.sender.SenderService"
            android:exported="false"
            android:process=":acra" />
enter code here

That,s why SendeService used in Acra was not starting.

like image 178
Usman Hashmi Avatar answered Oct 20 '22 09:10

Usman Hashmi


I want to write in application data folder

That is called internal data

I have created my own saver class to handle all of those savings:

import android.content.Context;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;

public class Saver {


    static FileOutputStream fos;

    static FileInputStream fis;


    public static void save(String filename, String data, Context c){




            try {

                fos = c.openFileOutput(filename, Context.MODE_PRIVATE);

                fos.write(data.getBytes());
                fos.close();

            } catch (Exception e) {

                // TODO Auto-generated catch block
                e.printStackTrace();
            }



    }



    String file;
    public String getFile(){return file;}

    public void setFile(String loc){
        file = loc;
    }

    String result;
    private static String mainLoad(String fn, Context c){
        String collected = null;
        try{

            fis = c.openFileInput(fn);
            byte[] dataArray = new byte[fis.available()];

            while(fis.read(dataArray) != -1){
                collected = new String(dataArray);
            }


        }catch(Exception e){
            e.printStackTrace();
            return null;

        }finally{
            try {
                fis.close();

                return collected;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }
        }


    }

    public static int loadInt(String fn, Context c){
        if(mainLoad(fn,c) == null) return 0;
        else return Integer.parseInt(mainLoad(fn,c));
    }
    public static double loadDouble(String fn, Context c){
        if(mainLoad(fn,c) == null) return 0;
        else return Double.parseDouble(mainLoad(fn,c));
    }

    public static float loadFloat(String fn, Context c){
        return Float.parseFloat(mainLoad(fn,c));
    }

    public static String loadString(String fn, Context c){
        return mainLoad(fn, c);
    }

    public static Boolean loadBoolean(String fn, Context c){
        if(mainLoad(fn,c) == null) return false;
        else return Boolean.parseBoolean(mainLoad(fn,c));
    }

    public static BigInteger loadBigInteger(String fn, Context c){

        return new BigInteger(mainLoad(fn,c));
    }

    public static BigDecimal loadBigDecimal(String fn, Context c){
        return new BigDecimal(mainLoad(fn,c));
    }

}

I want to write the crash report in text file using latest Acra 4.9.0. I can,t example for this latest version.

If you want to write to a .txt file on server, try this backend. Uses the default sender:

<?php
    // Outputs all POST parameters to a text file. The file name is the date_time of the report reception
    $fileName = date('Y-m-d_H-i-s').'.txt';
    $file = fopen($fileName,'w') or die('Could not create report file: ' . $fileName);
    foreach($_POST as $key => $value) {
    $reportLine = $key." = ".$value."\n";
        fwrite($file, $reportLine) or die ('Could not write to report file ' . $reportLine);
    }
    fclose($file);
?>

If you only want to write locally, then the point of ACRA disappears as you cannot get the files.

If you create .txt files to transmit them, it is actually better to use the backend I linked. It transmits the raw data, and you can get all your fields in a .txt file

like image 41
Zoe stands with Ukraine Avatar answered Oct 20 '22 07:10

Zoe stands with Ukraine