【问题标题】:Adding Geofence gives ApiException status 13添加地理围栏会提供 ApiException 状态 13
【发布时间】:2019-11-01 16:49:25
【问题描述】:

最近遇到一个问题,添加地理围栏会随机失败并出现 ApiException,状态代码 13 被定义为“错误”,没有提供额外的详细信息。

通常错误代码特定于地理围栏,但这似乎是一般故障。有谁知道为什么 GeofencingClient 会返回状态码 13?我一直找不到遇到同样问题的人。

这似乎影响了以前正常运行的应用程序的旧版本。

我已经仔细检查了纬度/经度是否为有效坐标,相同的数据有时也可以正常工作。我尝试使用不同的 API 密钥进行初始化,以防地图/位置服务出现问题,但这并没有什么不同。

我也尝试过从 GeofencingClient(context)LocationServices.getGeofencingClient(context) 没有变化。

我已经尝试升级库版本,没有区别。

定义了播放服务版本和 API 密钥的典型清单设置;

<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version"/>

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="@string/maps_api_key"/>

<service android:name=".GeofenceTransitionsIntentService"/>

地理围栏被添加到这里,并且没有任何结果到达意图服务

private val geofencingClient = GeofencingClient(context)

private val geofencePendingIntent =
            PendingIntent.getService(context, 0, Intent(context, GeofenceTransitionsIntentService::class.java), PendingIntent.FLAG_UPDATE_CURRENT)

fun setGeofence(latitude: Double, longitude: Double, radius: Float, geofenceId: String) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            val geofenceList = listOf(buildGeofence(latitude, longitude, radius, geofenceId))
            geofencingClient.addGeofences(getGeofencingRequest(geofenceList), geofencePendingIntent)?.run {
                addOnFailureListener {
                    // Failed to add geofences
                    geofenceErrorListener?.invoke("Failed to add Geofence: ${it.message}")
                }
            }
        }
    }

这直到最近才成为问题,现在几乎 100% 的时间都在发生。

com.google.android.gms.common.api.ApiException: 13:

编辑:从 PlayServices 版本 17.7.85(在我的设备上)开始,该问题似乎已在 Google 端得到解决

【问题讨论】:

  • 我这几天也有同样的问题
  • 我也遇到了这种情况,希望有人能提供解决方案:-)
  • +1,刚开始突然看到这个,没有发布任何更新。 Google 端或最新版本的 Google Play 服务一定有问题。希望它很快得到解决 - 我不确定我们是否能做些什么。
  • 是的,我想我已经追踪到 6 月 11 日对 Google Play 服务版本 17.x 的更新。在尚未更新的旧版本 16.x 上不会出现此问题。将通过电子邮件向 Play 服务团队发送电子邮件
  • @Ldawg - 你还在遇到这个问题吗?我不再有这个问题了,但我不确定我是否只是走运。我的 Google Play 服务没有更新或任何东西。谢谢!

标签: android google-play-services android-pendingintent android-geofence


【解决方案1】:

我正在使用 Android Q Beta 进行一些测试,并注意到如果我的应用具有新的“仅在使用应用时允许”位置权限,我总是会收到此错误。即使应用程序在前台,我也无法添加任何位置权限设置为“仅在使用应用程序时允许”的地理围栏,但只要我将应用程序的位置权限设置为“始终允许”,我就可以添加地理围栏没问题。

但是,我仍然在其他 API 版本上看到问题,所以很遗憾,它并没有真正完全解决问题。我有一台运行 Android 8.0 的设备和一台运行 Android 9.0 的设备,但我仍然偶尔会看到状态错误 #13。我不确定在这些设备上该怎么做,因为它们没有新的“仅在使用应用程序时允许”权限。他们都有完整的位置访问权限。

我添加此答案是因为它可能对一些运行 Android Q Beta 的用户有所帮助,或者至少有助于了解可能导致问题的原因。我确实认为这与最新的 Google Play 服务版本有关,因为我认为我们所做的一切都是正确的。

编辑: 如果有人有兴趣关注,我已经在 Google 的问题跟踪器上添加了一个问题... https://issuetracker.google.com/issues/135771329

【讨论】:

    【解决方案2】:

    Google 回复我们,告知我们他们已针对此问题进行了修复。我能够确认我的非工作设备现在正在工作。

    【讨论】:

    • 还可以确认,从我设备上的 PlayService 版本 17.7.85 开始,一切似乎都恢复了!
    【解决方案3】:

    如果您使用的是 API 29 或 android 10,phonethi 就是这种情况。您需要在清单中声明使用:

    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    

    而且,你请求权限,你必须同时请求:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    

    【讨论】:

      【解决方案4】:

      addGeofencesStatusException: 13 错误开始经常发生在我自己和我的应用程序用户身上,尽管没有对应用程序进行任何更改。在运行 Android 9 的各种设备上进行了观察。用户在 6 月中旬左右开始报告该问题。

      在此处阅读了相关内容后 - 感谢 @Ldawg@StephenRuda - 并将我的 cmets 添加到 google 问题中,我决定在添加地理围栏时对应用程序进行一些推测性更改。做了一些测试,在问题无法重现后,发布了 Beta,然后将 Production 发布到 Play 商店。新版本尚未观察到该问题。

      我发布我修改后的解决方案以防它对任何人有所帮助,但它在概念上与 Ldawg 最初发布的错误类似。此外,我还不能对以前的版本进行回归测试,看看它是否仍然像以前一样出现。由于这是一个没有描述的不透明错误,因此由 gms 内的不同状态引起的多个触发器并非不可想象。在 Google 自己确认这一点之前,该修复是推测性的,而且这个问题有些难以捉摸。

      我的修复中的基本变化是以前, rxLocationProvider.addGeofencesrxLocationProvider.removeGeofences 在每个位置的循环中多次调用,并观察到 ​​status 13 错误。

      更改后,rxLocationProvider.addGeofences 仅被调用一次,并带有 Geofence 对象列表。 rxLocationProvider.removeGeofences 还采用位置列表而不是单个位置。该应用使用 mcharmas android 反应位置库https://github.com/mcharmas/Android-ReactiveLocation

      StatusException: 13 之前的代码

      private GeofencingRequest createGeofencingRequest(String requestId) {
              Geofence geofence = new Geofence.Builder()
                      .setRequestId(requestId)
                      .setCircularRegion(stationInfo.getLat(), stationInfo.getLon(), GEOFENCE_RADIUS_METRES)
                      .setExpirationDuration(Geofence.NEVER_EXPIRE)
                      .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
                      .build();
              return new GeofencingRequest.Builder().addGeofence(geofence).build();
          }
      
      public void addGeofence(String locationCrs) {
              final GeofencingRequest geofencingRequest = createGeofencingRequest(locationCrs);
              final PendingIntent pendingIntent = createNotificationBroadcastPendingIntent();
      
              ArrayList<String> lists = new ArrayList<>();
              lists.add(locationCrs);
              rxLocationProvider
                      .removeGeofences(lists)
                      .flatMap((Function<Status, Observable<Status>>)
                              status -> rxLocationProvider.addGeofences(pendingIntent, geofencingRequest))
                      .subscribe(addGeofenceResult -> {
      
                      }, throwable -> {
                          // **Status 13 here**
                      }));
          }
      

      之后的代码 - 未观察到错误

      private GeofencingRequest getGeofencingRequest() {
              GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
              builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
              builder.addGeofences(geofenceList);
              return builder.build();
          }
      
      private Geofence createGeofence(String requestId) {
              return new Geofence.Builder()
                      .setRequestId(requestId)
                      .setCircularRegion(stationInfo.getLat(), stationInfo.getLon(), GEOFENCE_RADIUS_METRES)
                      .setExpirationDuration(Geofence.NEVER_EXPIRE)
                      .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
                      .build();
          }
      
      public void addGeofences(List<String> locs) {
              for (String loc : locs) {
                  Geofence request = createGeofence(loc);
                  geofenceList.add(request);
              }
      
              final PendingIntent pendingIntent = createNotificationBroadcastPendingIntent();
      
              disposable.add(rxLocationProvider
                      .removeGeofences(locs)
                      .flatMap((Function<Status, Observable<Status>>)
                              status -> rxLocationProvider.addGeofences(pendingIntent, getGeofencingRequest()))
                      .subscribe(addGeofenceResult -> {
      
                      }, throwable -> {
                          // **No Errors observed**
                      }));
          }
      

      【讨论】:

        【解决方案5】:

        在 android 8 9 10 或更高版本中的代码意图调用权限以使地理围栏工作 我用德克斯特

        Dexter.withActivity(this@Activity_Map)
                .withPermissions(
                        Manifest.permission.ACCESS_COARSE_LOCATION
                        ,Manifest.permission.ACCESS_FINE_LOCATION
                        ,Manifest.permission.ACCESS_BACKGROUND_LOCATION
                )
                .withListener(object: MultiplePermissionsListener {
                    override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
                        report?.let {
                            if(report.areAllPermissionsGranted()){
                                aktifkangps()
                                ambilshareddprefnip()
                                geofencingClient = LocationServices.getGeofencingClient(this@Activity_Map)      //drawgeo()
                                cekInternet()
                                with(sharedPreferences) {
                                    status = getString(loginmasuk.SP_NIP   , "0").toString()
                                }
                                if (status == "failed"){
                                    val imap = Intent(this@Activity_Map, Activity_ambil_lokasi::class.java)
                                    startActivity(imap)
                                    finish()
                                }
                    }
        

        【讨论】:

          【解决方案6】:

          在我将 compile 和 targetSdkVersion 更改为 29 后,我遇到了同样的问题。首先它说com.google.android.gms.common.api.apiexception 13
          对于这个错误,我将 build.gradle 中的所有依赖项更改为最新版本。
          在那之后,我发现了新的错误com.google.android.gms.common.api.apiexception 1004
          然后我像上面一样添加权限ACCESS_BACKGROUND_LOCATION,最后我的应用又好了!

          【讨论】:

            【解决方案7】:

            将此权限添加到清单文件中。

            1. 互联网
            2. ACCESS_FINE_LOCATION
            3. WAKE_LOCK
            4. ACCESS_COARSE_LOCATION
            5. ACCESS_BACKGROUND_LOCATION

            并且还尝试允许位置“每次”的权限,因为有时该权限仅在使用应用程序时才有效。 您应该始终允许权限。

            这样你不会得到“com.google.android.gms.common.api.ApiException: 13:”

            【讨论】:

            • 这个问题已经有一个可接受的答案。
            【解决方案8】:

            当应用的位置访问设置设置为 Allow only while using the app 时,我收到此错误。

            要解决此问题,请转到位置设置,找到您的应用并将设置更改为 Allow all the time

            【讨论】:

              猜你喜欢
              • 2018-06-21
              • 1970-01-01
              • 2013-10-05
              • 2018-04-16
              • 1970-01-01
              • 2019-03-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多