添加Geofence会使ApiException状态为13

时间:2019-06-19 02:38:33

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

最近遇到了一个问题,即添加地理围栏将随机失败,并显示ApiException,状态码13定义为“ ERROR”,未提供其他详细信息。

通常,错误代码特定于地理围栏,但这似乎是一般性故障。有谁知道为什么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端得到解决

8 个答案:

答案 0 :(得分:2)

如果您使用的是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" />

答案 1 :(得分:1)

addGeofences StatusException: 13错误对于我自己和我的应用程序用户来说是很常见的错误发生,尽管未对应用程序进行任何更改。在运行Android 9的各种设备上观察到。用户在6月中旬左右开始报告此问题。

在这里了解了这一点-感谢@Ldawg@StephenRuda-并将我的评论添加到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**
                }));
    }

答案 2 :(得分:1)

Google再次与我们联系,告知我们他们已解决此问题。我能够确认我的无法正常工作的设备正在运行。

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分:0)

在Android 8 9 10或更高版本中的代码意图调用权限中使地理围栏工作 我用的是dexter

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()
                        }
            }

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

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

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

答案 7 :(得分:0)

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

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