在因为 googleapis/java-translate 库为我的应用程序构建版本时看到冲突之前,我使用了这些行并且它运行良好:
val translate: Translate = TranslateOptions.newBuilder().setApiKey(API_KEY).build().service
val translations = translate.translate(
textsToTranslate,
Translate.TranslateOption.sourceLanguage(sourceLanguage),
Translate.TranslateOption.targetLanguage(targetLanguage)
)
然后,在构建发布时,我必须在 app/build.gradle 中添加一些额外的代码以使其正常工作。但是,我看到我的应用程序从 10Mo 增长到 15Mo。只是为了翻译一些文本而昂贵..
所以我决定自己使用最新的 Google Translate Api v3 进行这些翻译
link
像这样执行一个简单的 api 休息请求:
val jsonObjectResponse = JSONObject(translate(sourceLanguageCode = sourceLanguage, targetLanguageCode = targetLanguage, textsToTranslate).awaitString())
val translations = jsonObjectResponse.getJSONArray("translations").toArray { getJSONObject(it) }.map { it.getString("translatedText") }
其中“翻译”功能是: private fun translate(sourceLanguageCode: String, targetLanguageCode: String, textsToTranslate: List<String>): Request =
Fuel.post(path = "https://translation.googleapis.com/v3/projects/$PROJECT_ID:translateText?key=$API_KEY")
.header(Headers.ACCEPT to "application/json")
.jsonBody(
JSONObject().apply {
put("contents", JSONArray().apply {
textsToTranslate.forEach { text -> put(text) }
})
put("sourceLanguageCode", sourceLanguageCode)
put("targetLanguageCode", targetLanguageCode)
}.toString()
)
但它返回:“HTTP Exception 401 Unauthorhorized”。该链接没有提到 API_KEY 的使用,所以我想它与..注意:Fuel 只是 Kotlin/Android 的 HTTP 网络库,以避免样板代码。
恢复:使用 googleapis/java-translate 的第一个正在工作,但第二个(自定义)不起作用并返回:“HTTP Exception 401 Unautohorized”。
我哪里错了?
额外说明:我知道我现在不限于 android 应用程序的包名称,但在这里,我只想让它工作:)
编辑
编辑 - 2020 年 12 月 3 日
再见赏金 [400]
最终使用带有 REST 的 Google Translate API v2:
// portion of suspend function code
coroutineScope {
async(Dispatchers.IO) {
try {
//handleTranslateV3Response(requests, JSONObject(translateV3(sourceLanguageCode = sourceLanguage, targetLanguageCode = targetLanguage, textsToTranslate = textsToTranslate).awaitString()))
//handleTranslateV2Response(requests, JSONObject(translateV2RestrictedToApplication(targetLanguageCode = targetLanguage, textsToTranslate = textsToTranslate, signature = signature).awaitString()))
handleTranslateV2Response(requests, JSONObject(translateV2(targetLanguageCode = targetLanguage, textsToTranslate = textsToTranslate).awaitString()))
} catch (e: Exception) {
Timber.tag("Translate").e(e)
val message: String = "An error occurred while translating ${sourceLanguage} to ${targetLanguage}"
requests.mapIndexed { index, entityTranslationRequest ->
TranslationResponse.Error(message, entityTranslationRequest)
}
}
}
}
/**
* Usage of Google Translate API v2 without restriction
* This function works properly
*/
private fun translateV2(targetLanguageCode: String, textsToTranslate: List<String>): Request =
Fuel.post(path = "https://translation.googleapis.com/language/translate/v2?key=$API_KEY")
.header(Headers.ACCEPT to "application/json")
.jsonBody(
JSONObject().apply {
put("q", JSONArray().apply {
textsToTranslate.forEach { text -> put(text) }
})
put("target", targetLanguageCode)
}.toString()
)
.header(Headers.CONTENT_TYPE to "application/json; charset=utf-8")
private fun handleTranslateV2Response(requests: List<EntityTranslationRequest>, jsonObject: JSONObject): List<TranslationResponse> {
val translations = jsonObject.getJSONObject("data").getJSONArray("translations").toArray { getJSONObject(it) }.map { it.getString("translatedText") }
return requests.mapIndexed { index, entityTranslationRequest ->
TranslationResponse.Success(translations[index], entityTranslationRequest)
}
}
在此 API KEY 上使用 Android 应用程序限制时,以下代码不起作用。根据同一问题的 this stackoverflow link 和 this stackoverflow link 和 this stackoverflow link。
如果不使用处理 Auth2、凭据等的多个谷歌库之一,就没有正确的方法可以自己发送指纹......
/**
* Usage of Google Translate API v2 with restriction to android app
* This function doesn't work and returns a "HTTP Exception 403 Forbidden"
* @param signature SHA-1
*/
private fun translateV2RestrictedToApplication(signature: String, targetLanguageCode: String, textsToTranslate: List<String>): Request =
Fuel.post(path = "https://translation.googleapis.com/language/translate/v2?key=$API_KEY")
.header(Headers.ACCEPT to "application/json")
.header("X-Android-Package" to BuildConfig.APPLICATION_ID)
.header("X-Android-Cert" to signature.toLowerCase())
.jsonBody(
JSONObject().apply {
put("q", JSONArray().apply {
textsToTranslate.forEach { text -> put(text) }
})
put("target", targetLanguageCode)
}.toString()
)
.header(Headers.CONTENT_TYPE to "application/json; charset=utf-8")
下面是 v3 的代码,它不起作用,因为它需要似乎只能从 Google 库生成的 token ,而且我厌倦了到处 split 的文档,这让我感到恶心。 /**
* Usage of Google Translate API v3
* This function doesn't work and returns a "HTTP Exception 401 Unautorhorized"
*/
private fun translateV3(sourceLanguageCode: String, targetLanguageCode: String, textsToTranslate: List<String>): Request =
Fuel.post(path = "https://translation.googleapis.com/v3/projects/$PROJECT_ID:translateText")
.header(Headers.ACCEPT to "application/json")
.header(Headers.AUTHORIZATION to "Bearer {token provided by some Google libraries I guess}")
.jsonBody(
JSONObject().apply {
put("contents", JSONArray().apply {
textsToTranslate.forEach { text -> put(text) }
})
put("sourceLanguageCode", sourceLanguageCode)
put("targetLanguageCode", targetLanguageCode)
}.toString()
)
.header(Headers.CONTENT_TYPE to "application/json; charset=utf-8")
private fun handleTranslateV3Response(requests: List<EntityTranslationRequest>, jsonObject: JSONObject): List<TranslationResponse> {
val translations = jsonObject.getJSONArray("translations").toArray { getJSONObject(it) }.map { it.getString("translatedText") }
return requests.mapIndexed { index, entityTranslationRequest ->
TranslationResponse.Success(translations[index], entityTranslationRequest)
}
}
最佳答案
我从 IBM Watson Translator 得到了同样的错误并解决了它
所以我以为错误来了
必须在请求头中指定
我有 this教程作为在 v3 中完成它的最简单方法。
并开始您需要来自 header 的授权和内容类型请求,您需要这样做
//okhttp3 library used
fun doRequest(){
val json = """${data("en","fr","Hello World")}"""
val request = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
val response = Request.Builder()
.url("https://translation.googleapis.com/v3/projects/project-number-or-id/locations/us-central1:translateText")
.post(request)
.addHeader("Authorization", "Bearer YOUR_API_GOES_HERE")
.addHeader("Content-Type", "application/json; charset=utf-8")
.build()
val answer = client.newCall(response).execute().body()!!.string()
print(answer)
}
警告 : 如果 API_KEY 有“apikey SFKHNKSJH-CSDFSCU”这样的空间,你需要使用 this 将其转换为单个 key 一种工具fun data(fromLang: String, toLang: String, word: String): String{
return """{
"sourceLanguageCode": "${fromLang}",
"targetLanguageCodes": "${toLang}",
"contents": ["${word}"]
}"""
}
These文档可能会对您有所帮助。
关于android - 如何在 Android 项目中使用谷歌翻译 api v3 将 googleapis/java-translate 库转换为自定义 api 休息请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64820683/