Google 附近的 Play 服务注册失败 TOO_MANY_PENDING_INTENTS
Google Play Services Nearby registration failed with TOO_MANY_PENDING_INTENTS
在我的登录申请中,我们正在注册附近的 Google Play 服务,并在注销时取消注册(代码如下)。即使在注册期间,我们也总是先取消订阅,然后再订阅。
但在几次 logout/login 循环后,应用程序不断捕获 ApiException 消息 ApiException: 2801: Will exceed MAX_PENDING_INTENTS_PER_APP=5
我知道这个错误是什么意思,但据我所知,代码是先注销的。所以它不应该达到那个配额。
订阅代码,运行 登录时和信标更新时
val nearby = Nearby.getMessagesClient(app, MessagesOptions.Builder()
.setPermissions(NearbyPermissions.BLE)
.build())
val task = apis
.checkApiAvailability(nearby)
.onSuccessTask { nearby.unsubscribe(BeaconReceiver.generatePendingIntent(app)) }
.onSuccessTask {
return@onSuccessTask if (beacons.isEmpty()) {
// if beacons is empty, I don't have to register anything,
Tasks.forResult(null as Void?)
} else {
val messageFilter = MessageFilter.Builder()
beacons.forEach {
messageFilter.includeIBeaconIds(it.proximityUuid, it.major, it.minor)
}
val options = SubscribeOptions.Builder()
.setStrategy(Strategy.BLE_ONLY)
.setFilter(messageFilter.build())
.build()
nearby.subscribe(BeaconReceiver.generatePendingIntent(app), options)
}
}
// inside awaitResult there's Task.await, and catch/log exceptions
val result = awaitResult("Beacon", 30, task)
退订代码,每次登出运行,几乎和订阅一样
val nearby = Nearby.getMessagesClient(app, MessagesOptions.Builder()
.setPermissions(NearbyPermissions.BLE)
.build())
val geofence = GeofencingClient(app)
val task = GoogleApiAvailability.getInstance().checkApiAvailability(nearby, geofence)
.onSuccessTask { nearby.unsubscribe(BeaconReceiver.generatePendingIntent(app)) }
.onSuccessTask { geofence.removeGeofences(GeofenceReceiver.generatePendingIntent(app)) }
val result = awaitResult("SdkDisabled", 30, task)
和 PendingIntent 代码,它使用我们的显式 class 和静态请求代码:
val intent = Intent(context, BeaconReceiver::class.java)
return PendingIntent.getBroadcast(context, BEACON_REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT)
所以问题:
为什么会抛出异常,我该怎么做才能正确 unregister/unsubscribe?
取消订阅时删除对 getBroadcast()
的调用中的 PendingIntent.FLAG_CANCEL_CURRENT
。
取消订阅时,您需要提供 PendingIntent
您曾经订阅的那个 "matches"。通过使用 FLAG_CANCEL_CURRENT
,您将取消现有的 PendingIntent
并创建一个新的,显然新的 "match" 不是您订阅时使用的那个。
恕我直言,这是 Play 服务库中的错误,因为它没有使用正确的 "matching" 算法,因为 PendingIntent
应该 "match".
在我的登录申请中,我们正在注册附近的 Google Play 服务,并在注销时取消注册(代码如下)。即使在注册期间,我们也总是先取消订阅,然后再订阅。
但在几次 logout/login 循环后,应用程序不断捕获 ApiException 消息 ApiException: 2801: Will exceed MAX_PENDING_INTENTS_PER_APP=5
我知道这个错误是什么意思,但据我所知,代码是先注销的。所以它不应该达到那个配额。
订阅代码,运行 登录时和信标更新时
val nearby = Nearby.getMessagesClient(app, MessagesOptions.Builder()
.setPermissions(NearbyPermissions.BLE)
.build())
val task = apis
.checkApiAvailability(nearby)
.onSuccessTask { nearby.unsubscribe(BeaconReceiver.generatePendingIntent(app)) }
.onSuccessTask {
return@onSuccessTask if (beacons.isEmpty()) {
// if beacons is empty, I don't have to register anything,
Tasks.forResult(null as Void?)
} else {
val messageFilter = MessageFilter.Builder()
beacons.forEach {
messageFilter.includeIBeaconIds(it.proximityUuid, it.major, it.minor)
}
val options = SubscribeOptions.Builder()
.setStrategy(Strategy.BLE_ONLY)
.setFilter(messageFilter.build())
.build()
nearby.subscribe(BeaconReceiver.generatePendingIntent(app), options)
}
}
// inside awaitResult there's Task.await, and catch/log exceptions
val result = awaitResult("Beacon", 30, task)
退订代码,每次登出运行,几乎和订阅一样
val nearby = Nearby.getMessagesClient(app, MessagesOptions.Builder()
.setPermissions(NearbyPermissions.BLE)
.build())
val geofence = GeofencingClient(app)
val task = GoogleApiAvailability.getInstance().checkApiAvailability(nearby, geofence)
.onSuccessTask { nearby.unsubscribe(BeaconReceiver.generatePendingIntent(app)) }
.onSuccessTask { geofence.removeGeofences(GeofenceReceiver.generatePendingIntent(app)) }
val result = awaitResult("SdkDisabled", 30, task)
和 PendingIntent 代码,它使用我们的显式 class 和静态请求代码:
val intent = Intent(context, BeaconReceiver::class.java)
return PendingIntent.getBroadcast(context, BEACON_REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT)
所以问题:
为什么会抛出异常,我该怎么做才能正确 unregister/unsubscribe?
取消订阅时删除对 getBroadcast()
的调用中的 PendingIntent.FLAG_CANCEL_CURRENT
。
取消订阅时,您需要提供 PendingIntent
您曾经订阅的那个 "matches"。通过使用 FLAG_CANCEL_CURRENT
,您将取消现有的 PendingIntent
并创建一个新的,显然新的 "match" 不是您订阅时使用的那个。
恕我直言,这是 Play 服务库中的错误,因为它没有使用正确的 "matching" 算法,因为 PendingIntent
应该 "match".