android - 在 Android 4.2 上运行谷歌云语音 api
问题描述
我在 Android 4.2 设备上运行 io.grpc:grpc-okhttp 时遇到问题。
我已经使用 Credentials 实现了 SpeechClient,用于运行 Google 云语音到文本。在 Android 7.1 设备上我没有问题。问题发生在 Android 4.2
所以在我开始的时候我有
implementation 'io.grpc:grpc-okhttp:1.35.0'
implementation 'io.grpc:grpc-android:1.35.0'
implementation 'com.google.cloud:google-cloud-speech:1.24.0'
问题。
第一个问题是 SSL 的 TLS 安全性(在 Android 4.2 上太旧了)。为此,我添加了依赖项
implementation 'org.conscrypt:conscrypt-android:2.5.1'
并在我的 DialogFragment (正在运行代码)中实现
Security.insertProviderAt(Conscrypt.newProvider(), 1)
在我实施这个之后,我得到了
Duplicate class org.conscrypt.AbstractConscryptEngine found in modules jetified-conscrypt-android-2.5.1-runtime (org.conscrypt:conscrypt-android:2.5.1) and jetified-conscrypt-openjdk-uber-2.2.1 (org.conscrypt:conscrypt-openjdk-uber:2.2.1)
问题(很多重复的类)所以为了解决这个问题,我添加了
configurations { all { exclude group: "org.conscrypt", module: "conscrypt-openjdk-uber" } }
现在我收到此错误,因为 com.google.api.client 使用的是 Standard.UTF-8 而我的设备使用的是 Android 17。
com.google.api.gax.rpc.UnauthenticatedException: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Failed computing credential metadata
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:73)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60)
at com.google.api.gax.grpc.ExceptionResponseObserver.onErrorImpl(ExceptionResponseObserver.java:82)
at com.google.api.gax.rpc.StateCheckingResponseObserver.onError(StateCheckingResponseObserver.java:86)
at com.google.api.gax.grpc.GrpcDirectStreamController$ResponseObserverAdapter.onClose(GrpcDirectStreamController.java:149)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:689)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$900(ClientCallImpl.java:577)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:751)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:740)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Failed computing credential metadata
at io.grpc.Status.asRuntimeException(Status.java:533)
at com.google.api.gax.grpc.GrpcDirectStreamController$ResponseObserverAdapter.onClose(GrpcDirectStreamController.java:149)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:689)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$900(ClientCallImpl.java:577)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:751)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:740)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NoClassDefFoundError: java.nio.charset.StandardCharsets
at com.google.api.client.util.StringUtils.getBytesUtf8(StringUtils.java:51)
at com.google.api.client.json.webtoken.JsonWebSignature.signUsingRsaSha256(JsonWebSignature.java:571)
at com.google.auth.oauth2.JwtCredentials.refresh(JwtCredentials.java:125)
at com.google.auth.oauth2.JwtCredentials.getRequestMetadata(JwtCredentials.java:163)
at com.google.auth.oauth2.ServiceAccountJwtAccessCredentials.getRequestMetadata(ServiceAccountJwtAccessCredentials.java:365)
at com.google.auth.Credentials.blockingGetToCallback(Credentials.java:112)
at com.google.auth.oauth2.ServiceAccountJwtAccessCredentials.getRequestMetadata(ServiceAccountJwtAccessCredentials.java:341)
at io.grpc.auth.GoogleAuthLibraryCallCredentials.applyRequestMetadata(GoogleAuthLibraryCallCredentials.java:110)
at io.grpc.CallCredentials2.applyRequestMetadata(CallCredentials2.java:58)
at io.grpc.internal.CallCredentialsApplyingTransportFactory$CallCredentialsApplyingTransport.newStream(CallCredentialsApplyingTransportFactory.java:108)
at io.grpc.internal.ForwardingConnectionClientTransport.newStream(ForwardingConnectionClientTransport.java:49)
at io.grpc.internal.InternalSubchannel$CallTracingTransport.newStream(InternalSubchannel.java:671)
at io.grpc.internal.DelayedClientTransport$PendingStream.createRealStream(DelayedClientTransport.java:353)
at io.grpc.internal.DelayedClientTransport$PendingStream.access$300(DelayedClientTransport.java:341)
问题:
- 如何解决此问题并使用“ApiStreamObserver”运行语音?我尝试将“io.grpc:grpc-”库恢复到 1.0 版或其他版本,但后来我遇到了其他问题......
解决方案
我已经解决了这个问题并在 Github 上提交了示例项目
https://github.com/DjToMeK27/CloudGoogleSpeechToText/tree/main
我在这个项目中做了什么
- 下载https://github.com/GoogleCloudPlatform/android-docs-samples/blob/master/README.md
- 更改了 android-docs-samples-master\speech 项目 SpeechRecognitionClient 中的类
- 更改 AudoEmitter.kt 中的 AudioRecord 以支持 API 16
- 导入 org.conscrypt:conscrypt-android:2.5.1 库
- 必须从 google-cloud-speech 中排除组 org.conscrypt(在 build.gradle 中)
- 添加了 init { Security.insertProviderAt(Conscrypt.newProvider(), 1) } 让 Android 4.1 运行正确的 TLS 以使 GRC 工作
- 我下载了 https://github.com/googleapis项目
- 将 google-http-client 中找到的所有 StandardCharset 更改为 Charset.forName())
- 并且还改变了一些测试来工作
- https://imgur.com/a/iU7yjCZ(文件更改)
- 我已经构建了这个项目并添加了 .jar 文件,我在此处包含了这些文件
- 现在它起作用了!
推荐阅读
- android - RecyclerView、数据绑定和 ViewModel 没有数据
- policy - 在 APIC 上运行自定义策略时,如何解决“CALL 规则不可操作”错误?
- python - FlaskWTF 多个表单相同的页面,带有 1 个提交按钮
- datastax - dse 图 - 未创建 cassandra 键空间 _pvt
- powershell - 如何“获取”错误处理的异常上下文?
- python - 通过字典和多处理使用时,BackgroundSubtractor 类型不正确
- mysql - MySQL更新时重复主键错误
- winforms - 从 Windows 窗体应用程序激活 Office(Word、Excel 和 PP)文档
- python - Python Discord.py | 邀请链接 on_ready 问题
- html - 带有文本的背景图像