在Google Analytics中获取崩溃报告

Anu*_*Anu 9 android google-analytics

我希望收到有关崩溃报告的通知,因为我的Android应用程序的谷歌分析中未被捕获的异常.我跟着给出的步骤https://developers.google.com/analytics/devguides/collection/android/v4/exceptions#parsing 但我仍然不收到任何崩溃报告.我的应用程序运行时出现运行时异常.我将ga_reportUncaughtException的代码添加为true:

真正

在我的analytics.xml中.还有什么我需要添加才能在谷歌分析帐户中受到欢迎.请帮忙!

Oca*_*Oca 6

Analytics中存在一个未解决的问题.我在API 10到19的实际设备上遇到了相同的行为.

https://code.google.com/p/analytics-issues/issues/detail?id=443

EDIT1:删除了问题,只是为了回答所描述的问题.

EDIT2:我尝试使用Analytics ExceptionBuilder捕获并发送异常,但它不起作用.

看起来报告已发送(至少LogCat显示报告了崩溃),但Google不会处理它.

虽然Google回答了这个问题,但我正在使用此解决方法.我想这不是最好的解决方案,代码可以改进,但它适用于我:

  1. 我按照以下步骤在Google Analytics中创建了自定义维度https://support.google.com/analytics/answer/2709829?hl=zh-CN

  2. 在我的应用程序中,我使用Analytics ExceptionReporter类创建了一个自定义异常处理程序.当捕获到异常时,我得到堆栈跟踪并将其截断为150字节(实际上我只得到堆栈的第一行并将其截断为150个字符.我假设1Char = 1个字节).我必须截断它,因为它是发送自定义维度值时Google Analytics允许的最大长度.堆栈跟踪存储在共享首选项中,而不是发送.我试图直接发送它,但是一旦应用程序崩溃它就无法运行.

    package com.company.package;
    
    import java.lang.Thread.UncaughtExceptionHandler;
    
    import android.content.Context;
    
    import com.google.android.gms.analytics.ExceptionParser;
    import com.google.android.gms.analytics.ExceptionReporter;
    import com.google.android.gms.analytics.GoogleAnalytics;
    import com.google.android.gms.analytics.HitBuilders;
    import com.google.android.gms.analytics.Tracker;
    
    public class GoogleAnalyticsTracker {
    
        private static Tracker mTracker;
        private static GoogleAnalytics mGa;
        private Context mContext;
    
        public GoogleAnalyticsTracker(Context context, int resource) {
            mContext = context;
            mGa = GoogleAnalytics.getInstance(context);
            mTracker = getTracker(resource);
    
            Thread.setDefaultUncaughtExceptionHandler(new AnalyticsExceptionReporter(mTracker, 
                Thread.getDefaultUncaughtExceptionHandler(), context));
        }
    
        synchronized Tracker getTracker(int xmlResource) {
            return mGa.newTracker(xmlResource);
        }
    
        public void sendScreenLabel(String screenLabel) {
            mTracker.setScreenName(screenLabel);
            mTracker.send(new HitBuilders.AppViewBuilder().build());
        }
    
        public void sendCustomDimension(int index, String value) {
            mTracker.send(new HitBuilders.AppViewBuilder().setCustomDimension(index, value).build());
        }
    
        private class AnalyticsExceptionReporter extends ExceptionReporter {
    
            public AnalyticsExceptionReporter(Tracker tracker, UncaughtExceptionHandler originalHandler, Context context) {
                super(tracker, originalHandler, context);
                setExceptionParser(new AnalyticsExceptionParser());
            }
    
            @Override
            public void uncaughtException(Thread t, Throwable e) {
            String exceptionDescription =  getExceptionParser().getDescription(t.getName(), e);
    
                //Add code to store the exception stack trace in shared preferences
    
                super.uncaughtException(t, e);
            }
        }
    
        private class AnalyticsExceptionParser implements ExceptionParser {
    
            @Override
            public String getDescription(String arg0, Throwable arg1) {
                StringBuilder exceptionFirsLine = new StringBuilder();
                for (StackTraceElement element : arg1.getStackTrace()) {
                    exceptionFirsLine.append(element.toString());
                    break;
                }
    
                //150 Bytes is the maximum allowed by Analytics for custom dimensions values. Assumed that 1 Byte = 1 Character (UTF-8)
                String exceptionDescription = exceptionFirsLine.toString(); 
                if(exceptionDescription.length() > 150) 
                    exceptionDescription = exceptionDescription.substring(0, 149);
    
                return exceptionDescription;
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在OnStart()的MainActivity中,我检查共享首选项中是否存在任何存储的堆栈跟踪.如果是,我发送自定义维度并清除共享首选项.

    @Override
    protected void onStart() {
        super.onStart();
        String exception = getExceptionFromSharedPreferences(this);
        if(exception != null && !exception.isEmpty()) {
            MainApplication.googleAnalyticsTracker.sendCustomDimension(1, exception);
        } 
        clearExceptionFromSharedPreferences(this);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 最后,我在Google Analytics中创建了自定义报告

Google Analytics中的自定义报告配置

编辑3:

我意识到我只发送了fileName和lineNumber,而不是我的包中的ExceptionName和Exception的来源.通过添加代码来发送该信息,我改进了答案.

private class AnalyticsExceptionParser implements ExceptionParser {

    @Override
    public String getDescription(String arg0, Throwable arg1) {
        String exceptionDescription = getExceptionInfo(arg1, "", true) + getCauseExceptionInfo(arg1.getCause()); 

        //150 Bytes is the maximum allowed by Analytics for custom dimensions values. Assumed that 1 Byte = 1 Character (UTF-8)
        if(exceptionDescription.length() > 150) 
            exceptionDescription = exceptionDescription.substring(0, 150);

        return exceptionDescription;
    }
}
//#endregion

//#region PRIVATE METHODS
private String getCauseExceptionInfo(Throwable t) {
    String causeDescription = "";
    while(t != null && causeDescription.isEmpty()) {
        causeDescription = getExceptionInfo(t, "com.myPackageName", false);
        t = t.getCause();
    }
    return causeDescription;
}

private String getExceptionInfo(Throwable t, String packageName, boolean includeExceptionName) {
    String exceptionName = "";
    String fileName = "";
    String lineNumber = "";

    for (StackTraceElement element : t.getStackTrace()) {
        String className = element.getClassName().toString().toLowerCase();
        if(packageName.isEmpty() || (!packageName.isEmpty() && className.contains(packageName))){
            exceptionName = includeExceptionName ? t.toString() : "";
            fileName = element.getFileName();
            lineNumber = String.valueOf(element.getLineNumber());
            return exceptionName + "@" + fileName + ":" + lineNumber;
        }
    }
    return "";
}
Run Code Online (Sandbox Code Playgroud)


mit*_*nia 1

根据我的经验,您需要了解有关 Google Analytics 中的崩溃和异常的两件事:

1)仅存储基本信息 - Google Analytics只会保存异常的名称和引发异常的位置(代码文件和行号)。您在 GA 上无法访问除此之外的任何信息。这绝对不理想,如果您希望跟踪异常的实际内容(主要是调用堆栈),请使用 Google Play 或实现您自己的解决方案。

2)异常不是实时的。异常信息可能每天收集和更新一次,因此,如果您正在尝试异常并且没有立即看到它们,请给它一些时间。