0

Я ищу свежие идеи о страшной ошибке 5005: «Код состояния означает, что при попытке получить токен OAuth ». когда мой Watch Face пытается подключить Google API, созданный с помощью различных API-интерфейсов Fitness. Это все работает в моем локальном тестировании И когда я загружаю и запускаю свою версию RELEASE (бета). Однако, когда мой первый тестер попробовал это, он получает этот код ошибки при попытке подключить API.Google Исправлены ошибки авторизации (с ошибками 5005, 5000 и 5015) в приложении WatchFace, WatchConfig и сопутствующем приложении

UPDATE2: Я теперь отслеживал, что происходит, поэтому я собираюсь перечислить здесь свой последний рабочий код, а затем поговорить в ответ о том, что я обнаружил.

Существует 3 разных случая, когда я подключаюсь к API Google: Watch Face (рефери таймер: https://play.google.com/store/apps/details?id=com.pipperpublishing.soccerrefpro), связанный с ним Watch Config и приложение-компаньон на мобильном телефоне (телефон).

вахты:

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; 
    } 

Обратите внимание, что я не прошу разрешения WRITE для HISTORY_API. Когда я потом попытаться вставить SPEED и МЕСТОНАХОЖДЕНИЕ пригодности данных в магазине Google Fit, я использую этот код:

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())); 
    } 

} 

Запомнить эти считывание код, потому что я буду ссылаться на результатах в моем ответе.

Часы Config Разница здесь в том, что часы 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 областей, хотя в действительности я не ссылаться на HISTORY_API (или любой фитнес Api) в Config. Тем не менее, пользователь должен войти в Watch COnfig, чтобы включить мою настройку (KEY_FITNESS_? ниже), которая контролирует считывание данных датчиков в Watch Face.

Наконец, Mobile

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(); 
} 
+0

Исходя из ошибки: [UNKNOWN_AUTH_ERROR] (https://developers.google.ком/Android/справочник/COM/Google/Android/GMS/фитнес/FitnessStatusCodes). Дважды проверьте, следуете ли вы руководству в [Авторизация на Android] (https://developers.google.com/fit/android/authorization), и вы также можете проверить это руководство для использования [Объединить несколько файлов манифеста] (https://developer.android.com/studio/build/manifest-merge.html). Также вы можете включить код для авторизации вашего приложения. Надеюсь это поможет –

ответ

1

Наконец-то я получил ответ от Google о том, как useDefaultAccount работает за кулисами, и это влияет на то, какая учетная запись Fit написана/прочитана выше. Вот вопрос, который я задал:

Мне действительно нужен ответ на следующий вопрос, который в течение нескольких месяцев мучил мои испытания. Я использую Fitness Apis с лица часов Wear. Я использую «useDefaultAccount» в построителе клиента Google. Но какая учетная запись является дефолтом в этом случае? - учетная запись, используемая для загрузки приложения (в этом случае какая учетная запись используется при установке приложения с вашего компьютера-разработчика) - это null/unset - это учетная запись, которую вы выбираете для своего сопутствующего приложения при подключении. - это текущий счет, выбранный в Google Fit - вы не можете использовать useDefaultAccount в лицах Wear/приложения

И ответ от Google (спасибо Gustavo Моура): Вот как я понимаю логику (это не очень хорошо задокументированы, и мы намерены его очистить в ближайшем будущем): 1. Если есть приложение-компаньон, и пользователь подписал контракт с Fit и выбрал учетную запись, мы синхроним эту учетную запись с устройством Wear и будем использовать его , 2. Если нет сопутствующего приложения (или пользователь не подписал его), но пользователь установил и включил Google Fit и выбрал учетную запись с Fit, мы будем синхронизировать эту учетную запись с устройством Wear и использовать Это. 3. Если нет сопутствующего приложения и Google Fit, но устройство Wear имеет другое встроенное приложение, которое имеет аналогичное поведение (например, Moto Body на часах Motorola), мы будем использовать учетную запись из этого приложения. 4. Если ни одно из приведенных выше значений не является истинным, все еще существуют некоторые API, которые будут работать даже без учетной записи (например, запись счетчика шагов и запрос). Это особенность в том, что любые данные, доступные в этом режиме, будут локальными данными только для часов и никогда не будут синхронизированы с другими устройствами или серверами.

0

Вот результат моего тестирования с вышеприведенным кодом. Сначала я зашел на страницу учетных записей Google и убедился, что мое приложение было отменено из подключенных приложений.

Если я начинаю мобильное приложение, я получу попросил:

  • счет Google использовать для футбольного судьи Pro
  • Разрешить приложение, чтобы просмотреть местоположение и активность История
  • Грант для чтения разрешение календарь (используется в других местах) и в конце концов, когда я хочу, чтобы отобразить карту в поле охвата: разрешение
  • Grant Access Fine Расположение

Однако в моих тестах я сознательно не заходил в мобильное приложение.Вместо этого, когда я запускаю Watch Face: - мне предлагается предоставить разрешение на доступ к точному местоположению (я запускаю намерение Config Activity для обработки этой проверки/предоставления)

Затем я перехожу в Watch Config, чтобы установить длину периода и включите флаги коллекции Fitness. Конфигурация Watch никогда не запрашивает никаких разрешений, а не работает с разрешениями READ_WRITE.

Когда я закончу сбор данных на циферблате, я получаю следующий результат:

? D/RefWatchFace:: Listener registered for data Type com.google.speed 
? D/RefWatchFace:: Listener registered for data Type com.google.location.sample 
? D/RefWatchFace:: Detected -1 Activity datapoints; inserting 10 (including created ones) 
? D/RefWatchFace:: inserting final 10 activity segments (including created ones) 
? D/RefWatchFace:: Detected 10 Speed datapoints; inserting in 1 batches 
? D/RefWatchFace:: inserting final 10 Speed points (including created ones) 
? D/RefWatchFace:: Detected 16 Location datapoints; inserting in 1 batches 
? D/RefWatchFace:: inserting final 16 Location points (including created ones) 
? D/RefWatchFace:: Checking inserted fitness data for com.google.activity.segment in this batch time 1468440718000-1468441013000 
? D/RefWatchFace:: Successfully inserted Session Wed, Jul 13; 1:11PM: Period 1 
? D/RefWatchFace:: Checking inserted fitness data for com.google.speed in this batch time 1468440716000-1468440734000 
? D/RefWatchFace:: Checking inserted fitness data for com.google.location.sample in this batch time 1468440709575-1468440750000 
? D/RefWatchFace:: After insert; read-back found 9 data points for data type com.google.activity.segment 
? D/RefWatchFace:: After insert; read-back found 10 data points for data type com.google.speed 
? D/RefWatchFace:: After insert; read-back found 16 data points for data type com.google.location.sample 

Другими словами, ни в какой момент был я попросил предоставить разрешения на запись, но она все равно писал.

В моем втором тесте я удалил разрешения WRITE в приложении «Конфигурация часов» и повторно запустил Watch Face. Теперь все вставки возвращают код состояния 5005 (Неизвестная ошибка), , но данные о местоположении фактически вставлены (а не данные о скорости или активности).

В моем третьем тесте, я перемещаю разрешения WRITE на код Face Face Google Api. В этом случае .connect немедленно выходит из строя с ошибкой 5005.

Заключение: Мне кажется, что здесь есть хотя бы одно отверстие безопасности, а также непоследовательное поведение и совершенно бесполезные ошибки на стороне Wear.

Смежные вопросы