Android Crashlytics-限制网络访问

时间:2018-07-07 17:52:25

标签: android crashlytics crash-reports

我已经在缺乏在某些情况下限制Crashlytics网络使用的能力上工作了一段时间。例如-在漫游中,在计费网络中等等。

根据SDK文档,我发现只有两个选项可以解决此问题:

  • 在运行时通过不初始化Crashlytics来“选择退出”

  • 内置用户同意对话框,然后发送崩溃报告

此API的用途非常有限,因为:

  • 不初始化Crashlytics不仅阻止了网络访问,而且还防止了Crashlytics将在本地保存崩溃报告的任何机会,以便最终发送事件。更何况,除了残酷地重写Thread.setUncaughtExceptionHandler

  • 之外,没有其他方法可以退出运行时。 如果在后台发生崩溃,
  • 同意对话框对用户没有任何意义。

我的问题基本上是: 我想念什么吗? 有什么方法可以限制Crashlytics的网络访问?

我的动力来自防止在某些情况下我的应用使用网络带宽的情况可能会给用户造成经济损失的需求,尽管启用了“蜂窝网络”或“通过漫游使用数据”设备设置。

6 个答案:

答案 0 :(得分:7)

没有一种方法可以限制应用程序中Crashlytics的互联网使用。但是,我要解决的方法是为用户提供Crashlytics正在使用漫游的信息,或者只是将崩溃报告保存在本地,并在用户连接到wifi网络后将其发送给他们。另外,如果用户希望将崩溃报告保存在本地或通过漫游立即发送,也可以给用户选择。

  1. Save the ErrorLog locally在设备上
  2. 与wifi建立连接后,上传ErrorLog

您应该能够使用ConnectivityManager来获取Wi-Fi适配器的状态。从那里可以check if it is connected or even available

ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

if (mWifi.isConnected()) {
    // post error logs
}

答案 1 :(得分:6)

我是iOS / macOS的Crashlytics SDK的前维护者。我相对不熟悉Android版本的SDK,并且总体上绝对不熟悉Android。但是,我会试一试。

您想要做的是几次在iOS方面要求的操作。我本来会喜欢这样做的,因为强迫最终用户承担这些费用似乎非常糟糕。但是,iOS SDK的网络连接和启动例程非常复杂且非常微妙。确保交付崩溃并确保状态不一致的可能性为零,这具有很高的挑战性。我相信Android在这里更简单,但是我不能凭say地说。

但是,iOS SDK确实具有一些附加的客户端级别功能钩子。查看其中一种API的警告:

 *  @warning Just implementing this delegate method will disable all forms of synchronous report submission. This can
 *           impact the reliability of reporting crashes very early in application launch.

基本上,为了满足此特定API的约定,必须禁用某些提高报告可靠性的技术。问题是,有时这是值得的。许多应用程序决定进行此折衷。许多应用程序还延迟初始化Crashlytics,以获取额外的性能。这对报告的可靠性有巨大的影响,但这是应用程序开发人员必须做出的另一个权衡。

我认为您应该认真考虑仅在这些情况下不启用Crashlytics(如果可以轻松检测到它们)。也许Android甚至允许最终用户按应用程序执行此操作?在这种情况下,您将永远不会收到任何报告。我想您的用户群足够多样化,以致在这些情况下丢失一些报告不会那么可怕。或者,也许您希望将其作为面向用户的选项浮出水面。

您甚至可以做一些疯狂的事情,例如自己重写Thread.setUncaughtExceptionHandler,并在这种情况下将异常缓冲到磁盘上。然后,在情况好转时将其重播到Crashlytics。将其变成一个开源库。我敢打赌,人们会喜欢的!虽然可能不是Crashlytics的Android团队;)(嗨!)

这与Gastón上面提供的推荐基本上相同,只是我在iOS方面看到的一些额外背景信息。还要向Crashlytics人员发送电子邮件询问此问题。我认为这是个好主意。

答案 2 :(得分:6)

我们在应用程序中使用了两步过程,这既没有使用Mobile Network,也没有使用not related to roaming

  1. 将崩溃日志保存到应用数据分区(即设备上)中的文件中

    请参阅此link

  2. 在WiFi网络已连接时将崩溃数据上传到服务器

    public class ConnectivityStatusReceiver extends BroadcastReceiver {
    
      @Override
      public void onReceive(Context context, Intent intent) {
    
        final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    
        NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
    
        if (activeNetworkInfo != null && activeNetworkInfo.getTypeName() == "WIFI") {
          // post your crash logs to server
        }
      }
    }
    

答案 3 :(得分:5)

我正在阅读fabric上的文档,我发现了一些有趣的东西

  

Crashlytics在专用后台线程上处理异常,因此   对应用程序的性能影响很小。为了减少您的用户   网络流量,Crashlytics一起将记录的异常批处理   在应用下次启动时发送给他们。

因此,我正在考虑一种解决方法,因为在初始化应用程序时没有网络的崩溃正在发送,因此您可以在启动时提示用户任何对话框,告知他们是否要连接到互联网以发送崩溃报告来解决当前问题应用程序中的问题。 (因此,您在征得用户同意的情况下使用他们的网络数据)

这里的问题是我们不知道如何阻止crashlytics发送此报告,如果设备离线,他们会将它们存储在设备上,并在设备重新连接后发送回去,因为它声明{{ 3}}

另一种解决方法是,使用他们提供的自定义登录名记录重要的致命问题并发送给他们,您可以找到更多关于here

的信息。
  

确保发送崩溃报告对   您的用户设备上,Crashlytics日志的最大大小为64 KB。   当日志超过64 KB时,最早的记录值将被删除   为了维持这个阈值。

总而言之,在阅读了文档之后,无法禁用crashlytics来不断发送报告,您只能在希望用户发送或不发送报告时管理用户的网络连接。类似的连通性是目前启用和关闭crashlytics

它只是在谈论“减少网络流量”,而不是在根本上禁用crashlytics网络。

我想到的另一种方法是制作一个标志来启动crashlytics,然后在条件Crashlytics.start()内使用

要禁用它,只需执行以下操作

CrashlyticsCore core = new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build();
Fabric.with(this, new Crashlytics.Builder().core(core).build());

玩这两个东西是我认为目前有可能减少crashlytics的网络使用率的唯一方法

答案 4 :(得分:3)

您可以通过静态字段限制Crashlytics网络使用。

根据Crashlytics的值写入逻辑定义静态全局变量。

private static boolean INROAMING = false;

现在,您可以根据需要使用以下逻辑。就像不提供合作

if(isInternetIsConnected(this).equals("MOBILE")){
        if(INROAMING){
            //write your logic for context here, when phone is in roaming
            //restrict logic for crashlytics
        }else{
            //write your logic for context herem, when phone is not in roaming
            //un-restrict logic for crashlytics
        }
    }

public boolean checkForRoaming() {
        final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        PhoneStateListener phoneStateListener = new PhoneStateListener() {
            @Override
            public void onServiceStateChanged(ServiceState serviceState) {
                super.onServiceStateChanged(serviceState);
                if (telephonyManager.isNetworkRoaming()) {
                    // In Roaming
                    INROAMING = true;
                } else {
                    // Not in Roaming
                    INROAMING = false;
                }
                // You can also check roaming state using this
                if (serviceState.getRoaming()) {
                    // In Roaming
                    INROAMING = true;
                } else {
                    // Not in Roaming
                    INROAMING = false;
                }
            }
        };
    }

    public String isInternetIsConnected(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            assert cm != null;
            @SuppressLint("MissingPermission") NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) { // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    // connected to wifi
                    return "WIFI";

                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    // connected to the mobile provider's data plan
                    checkForRoaming();
                    return "MOBILE";
                }
            } else {
                // not connected to the internet
                return "NO CONNECTION";
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        return "NO CONNECTION";
    }
}

答案 5 :(得分:3)

没有一种方法可以限制应用程序中Crashlytics的互联网使用。如果用户希望将崩溃报告保存在本地或通过漫游立即发送崩溃报告,则可以给用户选择。

Save the ErrorLog locally on the device

与wifi建立连接后,上传ErrorLog。

您可以使用ConnectivityManager来获取网络状态。您可以检查它是否已连接甚至可用。

ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

if (mWifi.isConnected()) {
    // send error logs
}

Above code you can add in broadcastreceiver which will notify connection

示例:

 public class ConnectivityStatusReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {

  ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
  NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

  if (mWifi.isConnected()) {
   // send error logs
  }
 }
}