android – WatchFace,WatchConfig和随播应用中的Google Fit授权错误(5005,5000和5015错误)
作者:互联网
我正在寻找关于可怕的5005错误的一些新想法:“状态代码表示在尝试获取OAuth令牌时发生了未知错误.”当我的Watch Face尝试连接使用各种Fitness API构建的Google API时.这一切都适用于我的本地测试和下载并运行我的RELEASE(beta)版本.但是,当我的第一个测试人员试用它时,他在尝试连接API时会收到错误代码.
更新2:我现在已经跟踪了发生了什么,所以我将在这里列出我的最终工作代码,然后在答案中谈论我发现的内容.
我连接到Google API有3种不同的场合:Watch Face(裁判计时器:https://play.google.com/store/apps/details?id=com.pipperpublishing.soccerrefpro),相关的Watch Config以及Mobile(手机)上的配套应用程序.
看脸:
private GoogleApiClient buildGoogleClient() {
final GoogleApiClient googleApiClient;
final GoogleApiClient.Builder googleApiClientBuilder = new GoogleApiClient.Builder(RefWatchFaceService.this);
//Common components of the GoogleClient
googleApiClientBuilder
.addApi(Wearable.API)
.addApi(Fitness.SESSIONS_API) //set Session for each period)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.useDefaultAccount();
if (RefWatchUtil.isRefWatchPro()) {
googleApiClientBuilder
.addApi(Fitness.RECORDING_API) //records low power information
.addApiIfAvailable(Fitness.HISTORY_API
,new Scope(Scopes.FITNESS_ACTIVITY_READ)
,new Scope(Scopes.FITNESS_LOCATION_READ)
)
.addApiIfAvailable(Fitness.SENSORS_API
,new Scope(Scopes.FITNESS_ACTIVITY_READ)
,new Scope(Scopes.FITNESS_LOCATION_READ)
)
;
}
googleApiClient = googleApiClientBuilder.build();
return googleApiClient;
}
请注意,我不要求HISTORY_API的WRITE权限.当我稍后尝试在Google Fit商店中插入SPEED和LOCATION健身数据时,我使用以下代码:
private void insertFitnessDataSetBatch(final DataSet batchDataSet) {
final long batchStartTimeMillis = batchDataSet.getDataPoints().get(0).getTimestamp(TimeUnit.MILLISECONDS);
final long batchEndTimeMillis;
long tempEndTimeMillis = batchDataSet.getDataPoints().get(batchDataSet.getDataPoints().size()-1).getTimestamp(TimeUnit.MILLISECONDS);
//It's possible that this is called with one data point, in which case the Fitness insert will choke on same start and end time
if (tempEndTimeMillis > batchStartTimeMillis) {
batchEndTimeMillis = tempEndTimeMillis;
} else {
batchEndTimeMillis = batchStartTimeMillis + 1;
}
try {
Fitness.HistoryApi.insertData(mGoogleApiClient, batchDataSet)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
//Sometimes there is an error but the data was inserted anyway
readInsertedFitnessData(batchStartTimeMillis, batchEndTimeMillis, batchDataSet.getDataType());
if (!status.isSuccess()) {
Log.d(TAG, String.format("Inserting data type %s returned status Code %d (%s)",
batchDataSet.getDataType().getName(), status.getStatusCode(), status.getStatusMessage()));
}
}
});
} catch (RuntimeException e) {
Log.e(TAG, String.format("There was a runtime exception inserting the data set batch for type %s: %s",
batchDataSet.getDataType().getName(), e.getLocalizedMessage()));
}
}
记住这个回读代码,因为我会在我的回答中引用结果.
观看配置
这里的区别在于Watch Config扩展了FragmentActivity:
private GoogleApiClient buildGoogleClient() {
final GoogleApiClient googleApiClient;
final GoogleApiClient.Builder googleApiClientBuilder = new GoogleApiClient.Builder(this);
//Common components of the GoogleClient
googleApiClientBuilder
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.useDefaultAccount();
if (RefWatchUtil.isRefWatchPro()) {
googleApiClientBuilder
.addApiIfAvailable(Fitness.HISTORY_API
,new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)
,new Scope(Scopes.FITNESS_LOCATION_READ_WRITE)
);
}
googleApiClient = googleApiClientBuilder.build();
return googleApiClient;
}
请注意,我要求READ_WRITE范围,但实际上我没有在Config中引用HISTORY_API(或任何Fitness Api).但是,用户必须进入Watch COnfig打开我的设置(KEY_FITNESS_?下面),该设置控制在Watch Face中读取传感器数据.
最后,
移动
private GoogleApiClient buildGoogleClient() {
final GoogleApiClient.Builder googleApiClientBuilder;
googleApiClientBuilder = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApiIfAvailable(Wearable.API); //just in case you are using this without a Wear device
if (RefWatchUtil.isRefWatchPro()) {
googleApiClientBuilder
//.addApiIfAvailable(Fitness.SESSIONS_API)
.addApiIfAvailable(Fitness.HISTORY_API, //to read Location and other data per game
new Scope(Scopes.FITNESS_ACTIVITY_READ),
new Scope(Scopes.FITNESS_LOCATION_READ))
.useDefaultAccount();
}
return googleApiClientBuilder.build();
}
解决方法:
我终于得到了谷歌关于useDefaultAccount如何在幕后工作的答案,这会影响上面写的/正在阅读的Fit账号.这是我提出的问题:
我真的需要回答以下问题,这个问题一直困扰我的测试数月.我正在使用Wear表面上的Fitness Apis.我在Google客户端构建器中使用“useDefaultAccount”.但在这种情况下哪个帐户是默认帐户?
– 用于下载应用程序的帐户(在这种情况下,从您的开发计算机安装应用程序时使用的帐户)
– 它是null / unset
– 这是您在连接时选择随播应用的帐户.
– 这是在Google健身中选择的当前帐户
– 你不能在Wear faces / apps中使用useDefaultAccount
以及Google的回答(感谢Gustavo Moura):
这是我理解逻辑的方式(它没有很好的记录,我们打算在不久的将来清理它):
1.如果有一个配套应用,并且用户已登录Fit并在那里选择了一个帐户,我们会将该帐户同步到Wear设备并使用它.
2.如果没有配套应用(或用户尚未登录),但用户已安装并启用了Google健身,并选择了适合的帐户,我们会将该帐户同步到Wear设备并使用它.
3.如果没有配套应用程序且没有Google Fit,但Wear设备有另一个具有类似行为的内置应用程序(如摩托罗拉手表上的Moto Body),我们将使用该应用程序中的帐户.
4.如果以上都不是真的,那么即使没有帐户,仍然有一些API可以工作(如步数计数器记录和查询).这是特别的,因为在此模式下访问的任何数据都只是手表的本地数据,并且永远不会同步到任何其他设备或服务器.
标签:google-fit,google-fit-sdk,android,google-play-services,google-oauth 来源: https://codeday.me/bug/20190929/1834152.html