Android Crash report using ACRA ,BugSense and Parse.com
In my previous post I have described how to integrate ACRA and goolge form in order to get crash reports from Android application. Google as published new version of their form so it can no longer be used as ACRA report storage (more details can be found here). If you want to use ACRA and do not have your own server you need to choose other backends.I will present two options:
1. Using BugSense.
2. Using Parse.com.
Using BugSense
BugSense provide tools for monitor your mobile application. BugSense has crash report similar to ACRA but BugSense web server can also get ACRA reports without the need to download or use additional SDKs.
In order to integrate ACRA abd BugSense:
1. Open account in BugSense.
2. Define your application in BugSense dashboard
3. Create Android application class and add it to your project Manifest file.
2. Define your application in BugSense dashboard
3. Create Android application class and add it to your project Manifest file.
@ReportsCrashes(formUri = "http://www.bugsense.com/api/acra?api_key=YOUR_API_KEY", formKey="")
public class MyApp extends Application
{
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
ACRA.init(this);
}
Using Parse.com
Parse provides backend services for mobile and web application it also has push notifications services. It free addition provide about 1M requests per month. I will use Parse in order to store ACRA crash reports.
Integrating Parse and ACRA:
1. Register to Parse and download the SDK.
2. Create application in Parse website and get the application,client keys.
2. Create application in Parse website and get the application,client keys.
3. Add the SDK to you application Lib directory and add it to build path.
4. Verify that you have the following permissions in you Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5. You need to get Application key and Client key for your application (look at Parse application dashboard settings)
6. Create Android application class and add it to your project Manifest file.
7. Initialize parse sdk, ACRA and register report sender in the application class onCreate method.
import org.acra.ACRA;
import org.acra.ErrorReporter;
import org.acra.annotation.ReportsCrashes;
import android.app.Application;
import com.parse.Parse;
import com.parse.ParseObject;
@ReportsCrashes( formKey="")
public class MyApp extends Application
{
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Parse.initialize(this, Application key,Client key);
ACRA.init(this);
ErrorReporter.getInstance().setReportSender(new LocalSender(this));
}
}
7. The following code implements ACRA report sender that will send the crash report file to Parse.com. The code uses ParseFile and ParseObject (details).
import java.io.ByteArrayOutputStream;
public class LocalSender implements ReportSender {
private final Map<ReportField, String> mMapping = new HashMap<ReportField, String>() ;
private FileOutputStream crashReport = null;
private Context ctx;
public LocalSender(Context ct) {
ctx = ct;
}
public void send(CrashReportData report) throws ReportSenderException {
final Map<String, String> finalReport = remap(report);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
Log.i("hcsh","Report send");
try {
Set set = finalReport.entrySet();
Iterator i = set.iterator();
String tmp;
while (i.hasNext()) {
Map.Entry<String,String> me = (Map.Entry) i.next();
tmp = "[" + me.getKey() + "]=" + me.getValue();
buf.write(tmp.getBytes());
}
ParseFile myFile = new ParseFile("crash.txt", buf.toByteArray());
myFile.save();
ParseObject jobApplication = new ParseObject("AppCrash");
jobApplication.put("MyCrash", "Test App");
jobApplication.put("applicantResumeFile", myFile);
try {
jobApplication.save();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch (FileNotFoundException e) {
Log.e("TAG", "IO ERROR",e);
}
catch (IOException e) {
Log.e("TAG", "IO ERROR",e);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Map<String, String> remap(Map<ReportField, String> report) {
ReportField[] fields = ACRA.getConfig().customReportContent();
if (fields.length == 0) {
fields = ACRA.DEFAULT_REPORT_FIELDS;
}
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;
}
}
8. In case of crash the result on Parse dashboard will be :
Each crash will be display in separate row with report time stamp.
