I am trying to figure out how to add ACRA in my test project in Android Studio.
Following this article (which explains how to do it in Eclipse) https://github.com/ACRA/acra/wiki/BasicSetup, I have passed all so far up to the point where is explains to annotate your Application class with #ReportsCrashes. In this part, I dont know what to put as formUri.
I am just creating my own test app (API22 Lollipop) and trying to add ACRA support to it. I don't have any server, it is just a simple Android app.
import org.acra.*;
import org.acra.annotation.*;
#ReportsCrashes(
formKey = "", // This is required for backward compatibility but not used
formUri = "http://www.backendofyourchoice.com/reportpath"
)
public class MyApplication extends Application {
}
What do I put as the formUri?
Can you explain what formUri is for and how it works as I am new to dev?
Please explain
Thanks,
formUri points to your crash report server.
There are many to choose from, commercial and free.
The ACRA wiki lists several.
ACRAlyzer is one, but you will need to host it yourself.
Read about Acralyzer: https://github.com/ACRA/acralyzer/wiki/setup
It is simple backend for ACRA reports.
#ReportsCrashes(
formUri = "https://[your.couchdb.host]/acra-[yourappname]/_design/acra-storage/_update/report",
formUriBasicAuthLogin="[reporteruser]",
formUriBasicAuthPassword="[reporterpassword]",
reportType = org.acra.sender.HttpSender.Type.JSON,
httpMethod = org.acra.sender.HttpSender.Method.PUT,
....
)
public class [YourApplication] extends Application {
#Override
public final void onCreate() {
super.onCreate();
ACRA.init(this);
}
There you will find the usage of the Acralyzer user interface: https://github.com/ACRA/acralyzer/wiki/usermanual
Related
i tried setting up acra for my android project today, but it didnt work. I followed the instructions, importet the acra lib in gradle (compile 'ch.acra:acra:4.7.0')
Then i added this:
#ReportsCrashes(formKey = "", mailTo = "mail#adress.com", mode = ReportingInteractionMode.NOTIFICATION)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ACRA.init(this.getApplication());
I get the error Cannot resolve method 'formKey', but when deleting formkey from parameters, i get #ReportsCrashes not applicable to method
I also tried
#ReportsCrashes(formUri = "http://www.yourselectedbackend.com/reportpath")
and
#ReportsCrashes(formKey = "", formUri = "http://www.yourselectedbackend.com/reportpath")
and get the same errors. Anyone knows the issue/solution? The wiki at https://github.com/ACRA/acra/wiki seems outdated and there is no issue about this.
formKey has been removed for some time. I don't know where you saw instructions to use it, but they should no longer exist too. Use formUri.
You are getting #ReportsCrashes not applicable to method because you have annotated your onCreate method. You need to annotate your Application class
I am just about to release an app and I saw this stackoverflow question about things you should do before releasing an app. It tells me to use ACRA so I followed the instructions on this page.
So know I have a class called MyApplication like so :
import android.app.Application;
import org.acra.*;
import org.acra.annotation.*;
#ReportsCrashes(formKey = "", // will not be used
mailTo = "c#gmail.com",
mode = ReportingInteractionMode.TOAST,
customReportContent = { ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT },
resToastText = R.string.crash_report_text)
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// The following line triggers the initialization of ACRA
ACRA.init(this);
}
}
Now apparently when my application crashes I think the user is supposed to be able to send the report somehow, so I put a null pointer in my app but it just crashes and nothing happens. Am I supposed to do anything else?
I guess you might not have registered your application on BugSense
Where you want to send the crash reporst that depands on you only. When you are using Google Docs (deprecated now), you have to use your formKey you got from your google docs document.
If you want to store the reports on your own server, you can leave the formKey field blank. The only thing you have to do is to enter a valid url to your server (formUri = ....).
The other strings are for the type of dialog, which should or shouldn't appear.
Instead of using your own server, you can use BugSense. See this thread on stackoverflow.
As the use of Google Docs is deprecated for ACRA. I recommend you to use **BugSense** as your Back-End service:
1. Go to their site and sign in: http://www.bugsense.com/
2. Create a new project to monitor in BugSense site, as a result you will receive an API Key for this application.
3. Finally add this line to you Application class in you project:
#ReportsCrashes(formUri = "http://www.bugsense.com/api/acra?api_key=YOUR_API_KEY", formKey="")
Check out BugSense Docmentation
Am trying to send crash report from my applicatio to my domain or Mail but failed still.
To get the crash report in mail, I did
#ReportsCrashes(
formKey = "",
mailTo = "abc#gmail.com"
)
And the response is,
Sending file 1372758321000-approved.stacktrace
checkAndSendReports - finish
To get the crash report in my domain, I did
#ReportsCrashes(
formKey = "",
formUri = "http://www.abc.com/test1"
)
And the response is,
Sending file 1372856882000-approved.stacktrace
Failed to send crash report for 1372856882000-approved.stacktrace
org.acra.sender.ReportSenderException: Error while sending FORM report via Http POST
Any help will be handy for me and appreciated.
ACRA works for me sending reports by e-mail when I do exactly as they say in their docs:
#ReportsCrashes(mailTo = "reports#yourdomain.com", // my email here
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
https://github.com/ACRA/acra/wiki/Report-Destinations#sending-reports-by-email
You are probably forgetting the toast part. Or can it be you don't have an e-mail program (such as when you're running on the simulator).
I think sending reports by Google docs are not supported anymore.
Your application class should look like this.
import android.app.Application;
import org.acra.ACRA;
import org.acra.ReportField;
import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
#ReportsCrashes(mailTo = "user#domain.com", customReportContent = {
ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME,
ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL,
ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT},
mode = ReportingInteractionMode.TOAST, resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
ACRA.init(this);
}
}
No,not like Alex say,the mode property has no releation to the reporting type,you can see it in the source code in github
using the mailTo type,you should make sure that:
your app has the permission to connect network;
have an e-mail program in your device like Alex say;
have you invoked the ACRA.init(this) method in your application's oncreate()?
if all of these have done,then run your app,it will note you to configure the email,such as username and password and so on.
I'm attempting to follow the example tutorial at https://developers.google.com/eclipse/docs/endpoints-addentities and I'm stuck figuring out how to get the GameEndpoint.Builder class to generate within Eclipse.
After following this and generating the cloud endpoints as described, I have a GameEndpoint class created, but there is no GameEndpoint.Builder class. So obviously I have this error
GameEndpoint.Builder cannot be resolved to a type
I'm stumped at this point. How do I generate the GameEndpoint.Builder class within Eclipse, or what would prevent it?
Code
public class NewGameTask extends AsyncTask<Context, Integer, Long> {
protected Long doInBackground(Context... contexts) {
GameEndpoint.Builder endpointBuilder = new GameEndpoint.Builder(
AndroidHttp.newCompatibleTransport(), new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
}
});
GameEndpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
try {
Game game = new Game();
game.setStart(Calendar.getInstance());
Game result = endpoint.insertGame(game);
} catch (IOException e) {
e.printStackTrace();
}
return (long) 0;
}
}
I figured out my issue after watching this video from Google I/O 2013 which is using Android Studio, but it was the same thing as Eclipse mostly.
My mistake in following https://developers.google.com/eclipse/docs/endpoints-addentities was that you need to put your entity class into the MyApp-AppEngine project and NOT your MyApp project.
That was the source of confusion. In case it helps those in the future, here is a short breakdown of what I did.
Put the Entity class you want to add to App Engine into your MyApp-AppEngine project.
Right click your class and go to Google > Generate Cloud Endpoint Client Library
Right click your MyApp-AppEngine project and go to Google > Generate Cloud Enpoint Client Library
New references will be made in your MyApp project which you reference in your project for usage.
Note This answer is based on Android Studio, but am sure it's pretty much the same as Eclipse.
I also had this issue but later found the cause.Turns out I was importing the Endpoint class I generated instead of the endpoint Api package. Let me be clear.When you add the endpoint module to your project, you get the MyBean and MyEndpoint classes in the endpoint package. If you take a look at the guide to connecting your client to your backend, the EndpointsAsyncTask class uses:
private static MyApi myApiService = null;
Note how it uses MyApi instead of MyBean Now I was wondering where it got that from but I just have to take a look at my backend libraries:
The library marked 1 is the library first added to your project when you follow the guide previously mentioned. When I added a new class Student and autogenerated the cloud endpoint class, the second library was also added.
Long, boring story short; It is this library you should be importing and not the class.
import com.package-name.backend.studentApi.StudentApi;
and then using:
private static StudentApi myApiService = null;
...
StudentApi.Builder builder = new StudentApi.Builder(...)
instead of:
import com.package-name.backend.StudentEndpoint;
...
private static StudentEndpoint myApiService = null;
StudentEndpoint.Builder builder = new StudentEndpoint.Builder(...)
I got the same problem in Android Studio. I generated my Endpoint class from my entity java bean but when creating the AsyncTask, now way to get the Builder.
Actually (if I take a Game java bean like you) the Builder is not depending on the GameEndPoint but on the generated GameApi class.
In other words, I had to add these two imports in the AsyncTask class:
import com.examplepackage.backend.gameApi.GameApi;
import com.examplepackage.backend.gameApi.model.Game;
while the Game java bean that you wrote and the generated GameEndpoint are under package com.examplepackage.backend
I am using Log4j to log data in my android application. I have configured the log4j with the help of the following class, but the log files are not getting created.
console logging is enabled, maxfilesize and maxbackupsize are also good. please let me know what i am missing here.
public class ConfigureLog4J {
static LogConfigurator logConfigurator = new LogConfigurator();
private static final int maxFileSize = 1024 * 5; // 100KB
public static final int maxBackupSize = 2; // 2 backup files
public static final String LOG_FILE_NAME = "bitzer.log";
private static HashMap<Integer, Level> logLevelMap = new HashMap<Integer, Level>();
static {
logLevelMap.put(0, Level.OFF);
logLevelMap.put(1, Level.ERROR);
logLevelMap.put(2, Level.INFO);
logLevelMap.put(3, Level.WARN);
logLevelMap.put(4, Level.DEBUG);
logLevelMap.put(5, Level.ALL);
}
public static void startWithLogLevel(int logLevel) {
logConfigurator.setFileName(getLogFileName());
logConfigurator.setRootLevel(getLevelFromInt(logLevel));
logConfigurator.setUseFileAppender(true);
logConfigurator.setUseLogCatAppender(isConsoleLoggingEnabled());
logConfigurator.setMaxFileSize(getMaxFileSize());
logConfigurator.setMaxBackupSize(maxBackupSize);
// Set log level of a specific logger
// logConfigurator.setLevel("org.apache", Level.ERROR);
logConfigurator.setResetConfiguration(true);
logConfigurator.configure();
}
private static long getMaxFileSize() {
return CompanySettings.getInstance().getValueAsInteger(R.string.max_log_size);
}
private static boolean isConsoleLoggingEnabled() {
return CompanySettings.getInstance().getValueAsBoolean(R.string.consoleLoggingEnabled);
}
private static Level getLevelFromInt(int newLogLevel) {
return logLevelMap.get(newLogLevel);
}
public static String getLogsDirectory() {
if(AppData.getInstance().getContext()!=null)
{ String packageName = AppData.getInstance().getContext().getPackageName();
System.out.println("sundeep package name is not null and it's"+packageName);
return "data/data/" + packageName + "/logs/";
}
return null;
}
public static String getLogFileName() {
return getLogsDirectory() + LOG_FILE_NAME;
}
}
SLF4J Overview
I highly recommend you use SLF4J, which is log4j's "older brother" of sorts; the same developers who made log4j made SLF4J to address the shortcomings of log4j.
The difference is, whereas log4j is a full-fledged logging framework, SLF4J is a facade which you use directly in your Java code. The facade aspect allows you to plugin a concrete logging implementation — such as log4j, logback, Android's Log utility, etc. — at runtime.
It allows you to write code that can be used between different projects without having to go through your code and convert your logging statements to use the target project's logging framework. If you have several thousand lines of code which use log4j, but the target you're importing them into uses Apache Commons logging, you'll soon find yourself with a headache if you manually make the changes... even with the assistance of a capable IDE.
Using log4j in Android
There's a great Android library for logging to log4j — as well as many other logging frameworks as well — called android-logging-log4j. Check out the very excellent section on "Using log4j over slf4j", which is the route I take in my Android projects.
Examples from my own projects
Here are some examples from my own projects, such as my Awnry News & Weather app. (Yeah, shameless plug :P)
Required JARs on classpath
Basically these are the JARs I'll typically have in my project's classpath (version numbers vary as new releases come about, of course).
android-logging-log4j-1.0.3.jar
log4j-1.2.17.jar
slf4j-api-1.7.6.jar
slf4j-log4j12-1.7.6.jar
Instantiating a class's logger
And here's how I instantiate my general logger in each of my classes that require logging:
package com.awnry.android.naw;
...
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
public class NawApplication extends Application
{
private static final Logger log = LoggerFactory.getLogger(NawApplication.class);
As you can see, I'm only referencing SLF4J's Logger and LoggerFactory interfaces, even though the actual logging may eventually be accomplished using log4j or Android's Log.
That's the beauty of SLF4J's facade design: You aren't tied down to any specific logging implementation/framework; you can change your mind in the future without having to change a line of your code. If you're using log4j over SLF4J now, but in the future you want to use the Apache Commons Logging framework all you have to do is switch out the SLF4J-to-log4j bridge to a SLF4J-to-ACL bridge, and none of your Java code will be any wiser as it only calls SLF4J interfaces. The time-honored adage to code to an interface, not an implementation holds true once again, and SLF4J is a superb example of that.
Configuring the Android app's logging
In my Application.onCreate() method, I configure my logging like this:
#Override
public void onCreate()
{
...
String logFile = getFilesDir().getAbsolutePath() + File.separator + "logs" + File.separator + "debug.log";
log.info("Application log file: " + logFile);
LogConfigurator logConfigurator = new LogConfigurator(logFile, Level.TRACE);
logConfigurator.configure();
...
}
This part is actually optional, I believe. In my case I do this because I use the ACRA library to help catch unexpected program crashes and report the details back to me for debugging, so you might not need to define your android-logging-log4j's LogConfigurator as I do here.
Why you are using log4j.
There are efficient Log utility is available specially designed for android.
Use LogCat. Its very simple to use and standard way of putting log in your android app.