Ошибка: экземпляр OAuth2Credentials не поддерживает обновление токена доступа. Как создать экземпляр AccessToken со строкой значения токена? - PullRequest
0 голосов
/ 05 июля 2018

Я работаю над потоковой передачей речи в текст с помощью службы Google Speech to Text на Android. Вот официальный репозиторий образцов. Образец работает успешно. Но В качестве альтернативы вы должны получить токен доступа на стороне сервера и снабдить его клиентским приложением.

Итак, я настроил сервер и создал RESTful API для приложения, чтобы получить токен доступа. {"token":"1234567890sdertyuikjhgfghjk....."}

А также используйте api: https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={token} для получения информации о токене:

{
 "issued_to": "102073270616313859663",
 "audience": "102073270616313859663",
 "scope": "https://www.googleapis.com/auth/cloud-platform",
 "expires_in": 3600,
 "access_type": "offline"
}

Затем создайте экземпляр AccessToken: AccessToken token = new AccessToken(tokenValue, expiresIn);

Но следующая ошибка:

07-04 20:14:07.395 3023-3067/com.google.cloud.android.speech E/SpeechService: Error calling the API.
io.grpc.StatusRuntimeException: UNKNOWN
    at io.grpc.Status.asRuntimeException(Status.java:543)
    at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:395)
    at io.grpc.ClientInterceptors$CheckedForwardingClientCall.start(ClientInterceptors.java:202)
    at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:276)
    at io.grpc.stub.ClientCalls.asyncStreamingRequestCall(ClientCalls.java:266)
    at io.grpc.stub.ClientCalls.asyncBidiStreamingCall(ClientCalls.java:106)
    at com.google.cloud.speech.v1.SpeechGrpc$SpeechStub.streamingRecognize(SpeechGrpc.java:217)
    at com.google.cloud.android.speech.SpeechService.startRecognizing(SpeechService.java:264)
    at com.google.cloud.android.speech.MainActivity$1.onVoiceStart(MainActivity.java:62)
    at com.google.cloud.android.speech.VoiceRecorder$ProcessVoice.run(VoiceRecorder.java:199)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.IllegalStateException: OAuth2Credentials instance does not support refreshing the access token. An instance with a new access token should be used, or a derived type that supports refreshing.
    at com.google.auth.oauth2.OAuth2Credentials.refreshAccessToken(OAuth2Credentials.java:208)
    at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:175)
    at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:161)
    at com.google.cloud.android.speech.SpeechService$GoogleCredentialsInterceptor.getRequestMetadata(SpeechService.java:532)
    at com.google.cloud.android.speech.SpeechService$GoogleCredentialsInterceptor.access$900(SpeechService.java:450)
    at com.google.cloud.android.speech.SpeechService$GoogleCredentialsInterceptor$1.checkedStart(SpeechService.java:474)
    at io.grpc.ClientInterceptors$CheckedForwardingClientCall.start(ClientInterceptors.java:194)
    at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:276) 
    at io.grpc.stub.ClientCalls.asyncStreamingRequestCall(ClientCalls.java:266) 
    at io.grpc.stub.ClientCalls.asyncBidiStreamingCall(ClientCalls.java:106) 
    at com.google.cloud.speech.v1.SpeechGrpc$SpeechStub.streamingRecognize(SpeechGrpc.java:217) 
    at com.google.cloud.android.speech.SpeechService.startRecognizing(SpeechService.java:264) 
    at com.google.cloud.android.speech.MainActivity$1.onVoiceStart(MainActivity.java:62) 
    at com.google.cloud.android.speech.VoiceRecorder$ProcessVoice.run(VoiceRecorder.java:199) 
    at java.lang.Thread.run(Thread.java:764) 

Я мог бы использовать пример кода:

 final InputStream stream = getResources().openRawResource(R.raw.credential);
 final GoogleCredentials credentials = 
 GoogleCredentials.fromStream(stream).createScoped(SCOPE);
 final AccessToken token = credentials.refreshAccessToken();

и получите рабочий токен , и получите значение его токена с помощью getTokenValue() и получите время его истечения на getExpirationTime. Затем создайте экземпляр Token: AccessToken token = new AccessToken(tokenValue, expiresIn); вернуть экземпляр AccessToken. Но это вызовет ту же ошибку.

Поэтому мой вопрос заключается в том, как создать работающий экземпляр AccessToken, когда я получу строку значения токена и время истечения.

1 Ответ

0 голосов
/ 08 июля 2018

К сожалению, я до сих пор не могу создать рабочий AccessToken через конструктор. Но я использую сокет-сервер для решения проблемы. Потому что AccessToken уже имеет интерфейс Serializable. Так что намного проще общаться между клиентом и сервером.

Sever

private void  runServer() throws IOException, ClassNotFoundException{
    ServerSocket ss = new ServerSocket(port);

    Socket socket = ss.accept();
    ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
    ObjectInputStream is = new ObjectInputStream(socket.getInputStream());

    final InputStream stream = new ByteArrayInputStream(credential.getBytes(StandardCharsets.UTF_8));
    final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
                    .createScoped(SCOPE);
    final AccessToken token = credentials.refreshAccessToken();
    os.writeObject(token);
}
...