我正在构建通过本地(而非REST)Google Fit API与Google Fit集成的应用程序。我正在使用Flutter 1.2.1,Kotlin 1.3.21,com.google.android.gms:play-services-fitness:16.0.1,并在带有Google Play服务16.0.89的Android 8.1.0上运行该应用程序。>
一些HistoryClient.readData()请求消失而没有任何反馈(没有调用onSuccessListener,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)
我的理解是,本地Fitness服务(属于Google Play服务的一部分)未能发送有关失败的通知,或者我正在使用的客户端库向Google Fit传递失败。 这是正确的吗?
其他人如何使用此API解决此问题? 请问有多大的时间跨度才能合理确定它会在所有手机上成功完成?
注意:我曾尝试将其发布为https://issuetracker.google.com/issues/130402455上的错误,但没有得到回应,甚至不确定是不是正确的地方。
答案 0 :(得分:1)
class Account
{
private $user_name = NULL;
private $cxn; // database connection object
private $table_name;
private $message;
function __construct( mysqli $cxn,$table)
{
$this->cxn = $cxn;
if(is_string($table)) #17
{
$sql = "SHOW TABLES LIKE '$table'"; #19
$result = $this->cxn->query($sql);
if($result->num_rows > 0) #21
{
$this->table_name = $table;
}
else #25
{
throw new Exception("$table is not a table
in the database");
return FALSE;
}
}
else #32
{
throw new Exception("Second parameter is not a
valid table name");
return FALSE;
}
}
function selectAccount($user_name)
{
$user_name = trim($user_name); #42
$sql = "SELECT user_name FROM $this->table_name
WHERE user_name ='$user_name'"; #44
if(!$result = $this->cxn->query($sql))
{
throw new Exception("Couldn't execute query: "
.$this->cxn->error());
return FALSE;
}
if($result->num_rows < 1 ) #51
{
$this->message = "Account $user_name
does not exist!";
return FALSE;
}
else #57
{
$this->user_name = $user_name;
return TRUE;
}
}
function comparePassword($password)
{
if(!isset($this->user_name)) #66
{
throw new Exception("No account currently selected");
exit();
} #70
$sql = "SELECT user_name FROM $this->table_name
WHERE user_name ='$this->user_name' AND
password = md5('$password')";
if(!$result = $this->cxn->query($sql)) #74
{
throw new Exception("Couldn't execute query: "
.mysql_error());
exit();
}
if($result->num_rows < 1 ) #80
{
$this->message = "Incorrect password for
account $this->user_name!";
return FALSE;
}
else #86
return TRUE;
}
表示任何类型的服务/应用之间的数据交换都超过了Android允许的数据上限。通常,大小限制为200KB左右,但可能会有所不同(我不确定100%)。
解决方案是通过Google Fit API拆分您请求的数据,我认为您可以尝试通过在TransactionTooLargeException
中设置较短的时间范围来一次获取较少的数据。对于您而言,该错误表明您正在请求大约500KB的数据,这意味着您可以尝试将请求的时间跨度缩短到一半左右。
但是即使如此,实际的数据大小仍可能根据用户的活动而有很大的不同,并且一次多次请求太少也不理想,因此我认为您可以尝试在请求后设置计时器,并且如果过了一段时间仍未返回数据,请减少请求的时间跨度,然后重试(因为无法捕获错误)。
捕获错误的另一种方法是在单独的线程中读取日志,如果捕获了DataRequest
,它将回调并通知您减少请求的时间跨度。您可以像这样捕获日志:
TransactionTooLargeException
毫无疑问,这是Google的一个bug,因为他们没有考虑这种情况并捕获到该异常,这将是一个有效的bug报告。