添加地理围栏会提供 ApiException 状态 13

Posted

技术标签:

【中文标题】添加地理围栏会提供 ApiException 状态 13【英文标题】:Adding Geofence gives ApiException status 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 服务没有更新或任何东西。谢谢! 【参考方案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】:

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

    互联网 ACCESS_FINE_LOCATION WAKE_LOCK ACCESS_COARSE_LOCATION ACCESS_BACKGROUND_LOCATION

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

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

【讨论】:

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

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

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

【讨论】:

以上是关于添加地理围栏会提供 ApiException 状态 13的主要内容,如果未能解决你的问题,请参考以下文章

Android - 需要添加超过 100 个地理围栏

如何使地理围栏准确?

地理围栏 PendingIntent 始终为空

仅使用 gps 定位模式的 Android 地理围栏监控

设备重新启动后,地理围栏是不是在 android 中保持活动状态

iOS 7.1 地理围栏和 iBeacons 停止工作