Awareness API значительно задерживает обратные вызовы активности
Я создал класс и BroadcastReceiver, чтобы получать обратные вызовы из API осведомленности о том, когда заканчивается прогулка или бег. Я не получал своевременные обратные вызовы, и сначала подумал, что это потому, что я зарегистрировал "остановившийся" обратный вызов, но затем, немного отключив телефон, я получил несколько обратных вызовов! Но это было далеко от того времени, когда я перестал ходить. Не менее 5 минут после остановки. Иногда я не получаю обратные вызовы, даже когда приложение Google Fit записывает активность.
Так как я получил ответные звонки по крайней мере несколько раз, я знаю, что регистрация в порядке. Почему звонки задерживаются, а иногда и отсутствуют?
Для справки, я регистрирую эти обратные вызовы в onStart на главной активности, то есть initiateAwareness вызывается в это время, в пределах начала работы. И я никогда не отменяю их регистрацию. Я не собираюсь использовать его таким образом в производстве, это было только для тестирования. Плюс моя первоначальная попытка регистрации заборов в контексте приложения не удалась.
Вот вспомогательный класс, который я сделал, чтобы настроить регистрацию клиента Google и заборов.
public class AwarenessHelper {
public static final String WALKING_ENDED_FENCE = "walkingEndedKey";
public static final String RUNNING_ENDED_FENCE = "runningEndedKey";
public static final String TYPE_2_WALKING = "duringWalkingKey";
public static final String TYPE_2_RUNNING = "duringRunningKey";
private String tag = AwarenessHelper.class.getSimpleName();
public void initiateAwareness(final Activity context)
{
final GoogleApiClient googleApiClient = buildClient(context);
Log.d(tag, "Initiating blocking connect");
googleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(@Nullable Bundle bundle) {
if ( googleApiClient.isConnected() )
{
Log.d(tag, "Client connected, initiating awareness fence registration");
registerAwarenessFences(context, googleApiClient);
}
else
{
Log.d(tag, "Couldn't connect");
}
}
@Override
public void onConnectionSuspended(int i) {
}
});
googleApiClient.connect();
}
private void registerAwarenessFences(Context context, GoogleApiClient mGoogleApiClient) {
Awareness.FenceApi.updateFences(
mGoogleApiClient,
new FenceUpdateRequest.Builder()
.addFence(WALKING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
.addFence(RUNNING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
.addFence(TYPE_2_WALKING, DetectedActivityFence.during(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
.addFence(TYPE_2_RUNNING, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
.build())
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Log.i(tag, "Fence was successfully registered.");
} else {
Log.e(tag, "Fence could not be registered: " + status);
}
}
});
}
private GoogleApiClient buildClient(final Activity activity)
{
GoogleApiClient client = new GoogleApiClient.Builder(activity)
.addApi(Awareness.API)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if ( connectionResult.hasResolution() && connectionResult.getErrorCode() == CommonStatusCodes.SIGN_IN_REQUIRED )
{
try {
connectionResult.startResolutionForResult(activity, GOOGLE_FIT_AUTHORIZATION_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
}
})
.build();
return client;
}
private PendingIntent getBroadcastPendingIntent(Context context)
{
Intent intent = new Intent(AWARENESS_BROADCAST_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
return pendingIntent;
}
}
Вот BroadcastReceiver:
public class AwarenessHelper {
public static final String WALKING_ENDED_FENCE = "walkingEndedKey";
public static final String RUNNING_ENDED_FENCE = "runningEndedKey";
public static final String TYPE_2_WALKING = "duringWalkingKey";
public static final String TYPE_2_RUNNING = "duringRunningKey";
private String tag = AwarenessHelper.class.getSimpleName();
public void initiateAwareness(final Activity context)
{
final GoogleApiClient googleApiClient = buildClient(context);
Log.d(tag, "Initiating blocking connect");
googleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(@Nullable Bundle bundle) {
if ( googleApiClient.isConnected() )
{
Log.d(tag, "Client connected, initiating awareness fence registration");
registerAwarenessFences(context, googleApiClient);
}
else
{
Log.d(tag, "Couldn't connect");
}
}
@Override
public void onConnectionSuspended(int i) {
}
});
googleApiClient.connect();
}
private void registerAwarenessFences(Context context, GoogleApiClient mGoogleApiClient) {
Awareness.FenceApi.updateFences(
mGoogleApiClient,
new FenceUpdateRequest.Builder()
.addFence(WALKING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
.addFence(RUNNING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
.addFence(TYPE_2_WALKING, DetectedActivityFence.during(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
.addFence(TYPE_2_RUNNING, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
.build())
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Log.i(tag, "Fence was successfully registered.");
} else {
Log.e(tag, "Fence could not be registered: " + status);
}
}
});
}
private GoogleApiClient buildClient(final Activity activity)
{
GoogleApiClient client = new GoogleApiClient.Builder(activity)
.addApi(Awareness.API)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if ( connectionResult.hasResolution() && connectionResult.getErrorCode() == CommonStatusCodes.SIGN_IN_REQUIRED )
{
try {
connectionResult.startResolutionForResult(activity, GOOGLE_FIT_AUTHORIZATION_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
}
})
.build();
return client;
}
private PendingIntent getBroadcastPendingIntent(Context context)
{
Intent intent = new Intent(AWARENESS_BROADCAST_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
return pendingIntent;
}
}
Я получаю уведомления, но после большой задержки, а иногда и вовсе. Я начинаю деятельность много раз, так что, может быть, заборы регистрируются снова и снова? Это актуальный факт? Также подходит ли контекст службы или широковещательного приемника для инициализации осведомленных клиентов и ограждений?
1 ответ
Awareness
подписывается, чтобы получить ActivityRecognition
обновляется довольно редко, поэтому не очень неожиданно, что вы получите ответ через несколько минут.
Вы также должны беспокоиться о том, чтобы иметь слишком много заборов без отмены регистрации вообще.
Также нет причин иметь отдельный pendingIntent
для каждого из ваших заборов; вы могли бы иметь один pendingIntent
и добавить все заборы против этого. Используйте дополнительный ключ забора, чтобы различить результаты каждого забора. И снова делаю unregister
когда это имеет смысл. В противном случае заборы могут зависать даже после того, как ваше приложение исчезнет.