#android #google-fit #google-fit-sdk
#Android #google-fit #google-fit-sdk
Вопрос:
Я создаю приложение, интегрирующееся с Google Fit через локальный (не REST) API Google Fit. Я использую Flutter 1.2.1, Kotlin 1.3.21, com.google.android.gms: play-services-fitness: 16.0.1 и запускаю приложение на Android 8.1.0 с Google Play Services 16.0.89.
Некоторые запросы HistoryClient.ReadData() исчезают без какой-либо обратной связи (нет вызовов onsucclistener, onCancelledListener, onFailureListener, OnCompleteListener обратных вызовов), и в это время я вижу в журналах:
W/Fitness: Error delivering batch 0. Attempt #2
android.os.TransactionTooLargeException: data parcel size 572360 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:777)
at crb.c(:com.google.android.gms@16089017@16.0.89 (040306-239467275):1)
at yek.a(Unknown Source:8)
at yta.a(:com.google.android.gms@16089017@16.0.89 (040306-239467275):52)
at yta.a(:com.google.android.gms@16089017@16.0.89 (040306-239467275):31)
at ytc.run(:com.google.android.gms@16089017@16.0.89 (040306-239467275):44)
at rrt.b(:com.google.android.gms@16089017@16.0.89 (040306-239467275):32)
at rrt.run(:com.google.android.gms@16089017@16.0.89 (040306-239467275):21)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at rxx.run(Unknown Source:7)
at java.lang.Thread.run(Thread.java:764)
Насколько я понимаю, либо локальная служба фитнеса (часть сервисов Google Play) не отправляет уведомление о сбое, либо клиентская библиотека в Google Fit, которую я использую, не передает его.
Правильно ли это?
Как другие используют этот API для решения этой проблемы? Какой хороший промежуток времени следует запросить, чтобы быть достаточно уверенным в том, что он будет успешно завершен на всех телефонах?
Примечание: я попытался опубликовать это как ошибку на https://issuetracker.google.com/issues/130402455 , но я не получил ответа, и я даже не уверен, что это было подходящее место для этого.
Комментарии:
1. Я предполагаю
HistoryClient.readData()
, что запрашивается слишком много информации, что приведет к томуTransactionTooLargeException
, сможете ли вы случайно разделить информацию?2. @jackz314 Конечно, но насколько точно мне нужно его разделить? Я хотел, чтобы данные за месяц и однодневные части казались разумными, но иногда это исключение случается. Возможно, на моем телефоне он будет работать с шагом в полдня, но как насчет более медленных телефонов или учетных записей с большим количеством данных?
3. обычно, если объем данных превышает 200
TransactionTooLargeException
кб, выдается ошибка, поэтому я бы сказал, что сейчас запрашивается менее половины данных4. Я придумал способ записи журналов ошибок, это взлом, но, вероятно, это единственный возможный способ на данный момент, и он должен сработать, ознакомьтесь с моим ответом.
Ответ №1:
TransactionTooLargeException
означает, что обмен данными между службами / приложениями любого типа превысил допустимый верхний предел данных Android. Обычно ограничение по размеру составляет около 200 КБ, но оно может варьироваться (и я не уверен на 100%).
Решением было бы разделить запрашиваемые вами данные, просматривая API Google Fit, я думаю, вы можете попробовать получать меньше данных за раз, установив более короткий временной диапазон в DataRequest
. В вашем случае ошибка говорит о том, что вы запрашиваете около 500 КБ данных, что означает, что вы можете попытаться сократить временной интервал вашего запроса примерно до половины.
Но даже тогда фактический размер данных может сильно варьироваться в зависимости от действий пользователя, и не идеально запрашивать слишком мало за раз много раз, поэтому я думаю, вы могли бы попробовать настроить таймер после вашего запроса, и если через некоторое время данные не возвращаются, сократите временной интервал запроса и повторите попытку (поскольку зафиксировать ошибку невозможно).
Другим подходом к обнаружению ошибки было бы чтение журналов в отдельном потоке, и если он поймает TransactionTooLargeException
, он выполнит обратный вызов и уведомит вас об уменьшении временного интервала запроса. Вы можете записывать журналы следующим образом:
try {
Process process = Runtime.getRuntime().exec("logcat *:S Fitness:W");//only show Google Fitness related logs
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
if(line.contains("Error delivering batch")){
//do your callback here
}
}
}
catch (IOException e) {}
И поскольку исключение не генерируется, я бы сказал, что это ошибка со стороны Google, поскольку они не рассматривали эту ситуацию и не перехватывали это исключение, и это был бы действительный отчет об ошибке.